diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-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--; |