diff options
| -rw-r--r-- | fs/gfs2/rgrp.c | 66 |
1 files changed, 28 insertions, 38 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4d34887a601d..c9ed814eeb6f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -1961,7 +1961,7 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
| 1961 | * @dinode: 1 if this block is a dinode block, otherwise data block | 1961 | * @dinode: 1 if this block is a dinode block, otherwise data block |
| 1962 | * @nblocks: desired extent length | 1962 | * @nblocks: desired extent length |
| 1963 | * | 1963 | * |
| 1964 | * Lay claim to previously allocated block reservation blocks. | 1964 | * Lay claim to previously reserved blocks. |
| 1965 | * Returns: Starting block number of the blocks claimed. | 1965 | * Returns: Starting block number of the blocks claimed. |
| 1966 | * Sets *nblocks to the actual extent length allocated. | 1966 | * Sets *nblocks to the actual extent length allocated. |
| 1967 | */ | 1967 | */ |
| @@ -1970,19 +1970,17 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
| 1970 | { | 1970 | { |
| 1971 | struct gfs2_blkreserv *rs = ip->i_res; | 1971 | struct gfs2_blkreserv *rs = ip->i_res; |
| 1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; | 1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; |
| 1973 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 1974 | struct gfs2_bitmap *bi; | 1973 | struct gfs2_bitmap *bi; |
| 1975 | u64 start_block = gfs2_rs_startblk(rs); | 1974 | u64 start_block = gfs2_rs_startblk(rs); |
| 1976 | const unsigned int elen = *nblocks; | 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 | bi = rs->rs_bi; | 1977 | bi = rs->rs_bi; |
| 1982 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1978 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
| 1983 | 1979 | ||
| 1984 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { | 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 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, | 1984 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, |
| 1987 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 1985 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); |
| 1988 | rs->rs_biblk++; | 1986 | rs->rs_biblk++; |
| @@ -1991,20 +1989,12 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
| 1991 | BUG_ON(!rgd->rd_reserved); | 1989 | BUG_ON(!rgd->rd_reserved); |
| 1992 | rgd->rd_reserved--; | 1990 | rgd->rd_reserved--; |
| 1993 | dinode = false; | 1991 | dinode = false; |
| 1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | ||
| 1995 | } | 1992 | } |
| 1996 | 1993 | ||
| 1997 | if (!rs->rs_free) { | 1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); |
| 1998 | struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; | 1995 | if (!rs->rs_free || *nblocks != elen) |
| 1999 | |||
| 2000 | gfs2_rs_deltree(rs); | 1996 | gfs2_rs_deltree(rs); |
| 2001 | /* -nblocks because we haven't returned to do the math yet. | 1997 | |
| 2002 | I'm doing the math backwards to prevent negative numbers, | ||
| 2003 | but think of it as: | ||
| 2004 | if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ | ||
| 2005 | if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) | ||
| 2006 | rg_mblk_search(rgd, ip); | ||
| 2007 | } | ||
| 2008 | return start_block; | 1998 | return start_block; |
| 2009 | } | 1999 | } |
| 2010 | 2000 | ||
| @@ -2037,34 +2027,34 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
| 2037 | if (ip->i_res->rs_requested == 0) | 2027 | if (ip->i_res->rs_requested == 0) |
| 2038 | return -ECANCELED; | 2028 | return -ECANCELED; |
| 2039 | 2029 | ||
| 2040 | /* Check if we have a multi-block reservation, and if so, claim the | 2030 | /* If we have a reservation, claim blocks from it. */ |
| 2041 | next free block from it. */ | ||
| 2042 | if (gfs2_rs_active(ip->i_res)) { | 2031 | if (gfs2_rs_active(ip->i_res)) { |
| 2043 | BUG_ON(!ip->i_res->rs_free); | 2032 | BUG_ON(!ip->i_res->rs_free); |
| 2044 | rgd = ip->i_res->rs_rgd; | 2033 | rgd = ip->i_res->rs_rgd; |
| 2045 | block = claim_reserved_blks(ip, dinode, nblocks); | 2034 | block = claim_reserved_blks(ip, dinode, nblocks); |
| 2046 | } else { | 2035 | if (*nblocks) |
| 2047 | rgd = ip->i_rgd; | 2036 | goto found_blocks; |
| 2037 | } | ||
| 2048 | 2038 | ||
| 2049 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) | 2039 | rgd = ip->i_rgd; |
| 2050 | goal = ip->i_goal - rgd->rd_data0; | ||
| 2051 | else | ||
| 2052 | goal = rgd->rd_last_alloc; | ||
| 2053 | |||
| 2054 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
| 2055 | |||
| 2056 | /* Since all blocks are reserved in advance, this shouldn't | ||
| 2057 | happen */ | ||
| 2058 | if (blk == BFITNOENT) { | ||
| 2059 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", | ||
| 2060 | *nblocks); | ||
| 2061 | printk(KERN_WARNING "FULL=%d\n", | ||
| 2062 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
| 2063 | goto rgrp_error; | ||
| 2064 | } | ||
| 2065 | 2040 | ||
| 2066 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | 2041 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) |
| 2042 | goal = ip->i_goal - rgd->rd_data0; | ||
| 2043 | else | ||
| 2044 | goal = rgd->rd_last_alloc; | ||
| 2045 | |||
| 2046 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
| 2047 | |||
| 2048 | /* Since all blocks are reserved in advance, this shouldn't happen */ | ||
| 2049 | if (blk == BFITNOENT) { | ||
| 2050 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); | ||
| 2051 | printk(KERN_WARNING "FULL=%d\n", | ||
| 2052 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
| 2053 | goto rgrp_error; | ||
| 2067 | } | 2054 | } |
| 2055 | |||
| 2056 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | ||
| 2057 | found_blocks: | ||
| 2068 | ndata = *nblocks; | 2058 | ndata = *nblocks; |
| 2069 | if (dinode) | 2059 | if (dinode) |
| 2070 | ndata--; | 2060 | ndata--; |
