Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes

Pull GFS2 fixes from Steven Whitehouse:
"Here are three GFS2 fixes for the current kernel tree. These are all
related to the block reservation code which was added at the merge
window. That code will be getting an update at the forthcoming merge
window too. In the mean time though there are a few smaller issues
which should be fixed.

The first patch resolves an issue with write sizes of greater than 32
bits with the size hinting code. The second ensures that the
allocation data structure is initialised when using xattrs and the
third takes into account allocations which may have been made by other
nodes which affect a reservation on the local node."

* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes:
GFS2: Take account of blockages when using reserved blocks
GFS2: Fix missing allocation data for set/remove xattr
GFS2: Make write size hinting code common

+63 -46
+27 -4
fs/gfs2/file.c
··· 323 323 } 324 324 325 325 /** 326 + * gfs2_size_hint - Give a hint to the size of a write request 327 + * @file: The struct file 328 + * @offset: The file offset of the write 329 + * @size: The length of the write 330 + * 331 + * When we are about to do a write, this function records the total 332 + * write size in order to provide a suitable hint to the lower layers 333 + * about how many blocks will be required. 334 + * 335 + */ 336 + 337 + static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) 338 + { 339 + struct inode *inode = filep->f_dentry->d_inode; 340 + struct gfs2_sbd *sdp = GFS2_SB(inode); 341 + struct gfs2_inode *ip = GFS2_I(inode); 342 + size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; 343 + int hint = min_t(size_t, INT_MAX, blks); 344 + 345 + atomic_set(&ip->i_res->rs_sizehint, hint); 346 + } 347 + 348 + /** 326 349 * gfs2_allocate_page_backing - Use bmap to allocate blocks 327 350 * @page: The (locked) page to allocate backing for 328 351 * ··· 405 382 if (ret) 406 383 return ret; 407 384 408 - atomic_set(&ip->i_res->rs_sizehint, 409 - PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); 385 + gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); 410 386 411 387 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 412 388 ret = gfs2_glock_nq(&gh); ··· 685 663 if (ret) 686 664 return ret; 687 665 688 - atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); 666 + gfs2_size_hint(file, pos, writesize); 667 + 689 668 if (file->f_flags & O_APPEND) { 690 669 struct gfs2_holder gh; 691 670 ··· 812 789 if (unlikely(error)) 813 790 goto out_uninit; 814 791 815 - atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); 792 + gfs2_size_hint(file, offset, len); 816 793 817 794 while (len > 0) { 818 795 if (len < bytes)
+6 -2
fs/gfs2/inode.c
··· 1722 1722 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 1723 1723 ret = gfs2_glock_nq(&gh); 1724 1724 if (ret == 0) { 1725 - ret = generic_setxattr(dentry, name, data, size, flags); 1725 + ret = gfs2_rs_alloc(ip); 1726 + if (ret == 0) 1727 + ret = generic_setxattr(dentry, name, data, size, flags); 1726 1728 gfs2_glock_dq(&gh); 1727 1729 } 1728 1730 gfs2_holder_uninit(&gh); ··· 1759 1757 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 1760 1758 ret = gfs2_glock_nq(&gh); 1761 1759 if (ret == 0) { 1762 - ret = generic_removexattr(dentry, name); 1760 + ret = gfs2_rs_alloc(ip); 1761 + if (ret == 0) 1762 + ret = generic_removexattr(dentry, name); 1763 1763 gfs2_glock_dq(&gh); 1764 1764 } 1765 1765 gfs2_holder_uninit(&gh);
+30 -40
fs/gfs2/rgrp.c
··· 1961 1961 * @dinode: 1 if this block is a dinode block, otherwise data block 1962 1962 * @nblocks: desired extent length 1963 1963 * 1964 - * Lay claim to previously allocated block reservation blocks. 1964 + * Lay claim to previously reserved blocks. 1965 1965 * Returns: Starting block number of the blocks claimed. 1966 1966 * Sets *nblocks to the actual extent length allocated. 1967 1967 */ ··· 1970 1970 { 1971 1971 struct gfs2_blkreserv *rs = ip->i_res; 1972 1972 struct gfs2_rgrpd *rgd = rs->rs_rgd; 1973 - struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1974 1973 struct gfs2_bitmap *bi; 1975 1974 u64 start_block = gfs2_rs_startblk(rs); 1976 1975 const unsigned int elen = *nblocks; 1977 1976 1978 - /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ 1979 - gfs2_assert_withdraw(sdp, rgd); 1980 - /*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/ 1981 1977 bi = rs->rs_bi; 1982 1978 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); 1983 1979 1984 1980 for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { 1985 - /* Make sure the bitmap hasn't changed */ 1981 + if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, 1982 + bi->bi_len, rs->rs_biblk) != GFS2_BLKST_FREE) 1983 + break; 1986 1984 gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, 1987 1985 dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); 1988 1986 rs->rs_biblk++; ··· 1989 1991 BUG_ON(!rgd->rd_reserved); 1990 1992 rgd->rd_reserved--; 1991 1993 dinode = false; 1992 - trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); 1993 1994 } 1994 1995 1995 - if (!rs->rs_free) { 1996 - struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; 1997 - 1996 + trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); 1997 + if (!rs->rs_free || *nblocks != elen) 1998 1998 gfs2_rs_deltree(rs); 1999 - /* -nblocks because we haven't returned to do the math yet. 2000 - I'm doing the math backwards to prevent negative numbers, 2001 - but think of it as: 2002 - if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ 2003 - if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) 2004 - rg_mblk_search(rgd, ip); 2005 - } 1999 + 2006 2000 return start_block; 2007 2001 } 2008 2002 ··· 2027 2037 if (ip->i_res->rs_requested == 0) 2028 2038 return -ECANCELED; 2029 2039 2030 - /* Check if we have a multi-block reservation, and if so, claim the 2031 - next free block from it. */ 2040 + /* If we have a reservation, claim blocks from it. */ 2032 2041 if (gfs2_rs_active(ip->i_res)) { 2033 2042 BUG_ON(!ip->i_res->rs_free); 2034 2043 rgd = ip->i_res->rs_rgd; 2035 2044 block = claim_reserved_blks(ip, dinode, nblocks); 2036 - } else { 2037 - rgd = ip->i_rgd; 2038 - 2039 - if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) 2040 - goal = ip->i_goal - rgd->rd_data0; 2041 - else 2042 - goal = rgd->rd_last_alloc; 2043 - 2044 - blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); 2045 - 2046 - /* Since all blocks are reserved in advance, this shouldn't 2047 - happen */ 2048 - if (blk == BFITNOENT) { 2049 - printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", 2050 - *nblocks); 2051 - printk(KERN_WARNING "FULL=%d\n", 2052 - test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); 2053 - goto rgrp_error; 2054 - } 2055 - 2056 - block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); 2045 + if (*nblocks) 2046 + goto found_blocks; 2057 2047 } 2048 + 2049 + rgd = ip->i_rgd; 2050 + 2051 + if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) 2052 + goal = ip->i_goal - rgd->rd_data0; 2053 + else 2054 + goal = rgd->rd_last_alloc; 2055 + 2056 + blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); 2057 + 2058 + /* Since all blocks are reserved in advance, this shouldn't happen */ 2059 + if (blk == BFITNOENT) { 2060 + printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); 2061 + printk(KERN_WARNING "FULL=%d\n", 2062 + test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); 2063 + goto rgrp_error; 2064 + } 2065 + 2066 + block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); 2067 + found_blocks: 2058 2068 ndata = *nblocks; 2059 2069 if (dinode) 2060 2070 ndata--;