aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2013-11-25 06:16:25 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-01-03 04:58:08 -0500
commit5ea5050cec9c02e86ceb5e707a889003f895a690 (patch)
tree782554af83cacb80322874654782709dddd4174e /fs/gfs2/rgrp.c
parent1330edbeaf304703052fb583dd660b96309e4536 (diff)
GFS2: Implement a "rgrp has no extents longer than X" scheme
With the preceding patch, we started accepting block reservations smaller than the ideal size, which requires a lot more parsing of the bitmaps. To reduce the amount of bitmap searching, this patch implements a scheme whereby each rgrp keeps track of the point at this multi-block reservations will fail. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 1ccf89ab42b6..797f1d3114ef 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -641,9 +641,13 @@ static void __rs_deltree(struct gfs2_blkreserv *rs)
641 /* return reserved blocks to the rgrp */ 641 /* return reserved blocks to the rgrp */
642 BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free); 642 BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free);
643 rs->rs_rbm.rgd->rd_reserved -= rs->rs_free; 643 rs->rs_rbm.rgd->rd_reserved -= rs->rs_free;
644 /* The rgrp extent failure point is likely not to increase;
645 it will only do so if the freed blocks are somehow
646 contiguous with a span of free blocks that follows. Still,
647 it will force the number to be recalculated later. */
648 rgd->rd_extfail_pt += rs->rs_free;
644 rs->rs_free = 0; 649 rs->rs_free = 0;
645 clear_bit(GBF_FULL, &bi->bi_flags); 650 clear_bit(GBF_FULL, &bi->bi_flags);
646 smp_mb__after_clear_bit();
647 } 651 }
648} 652}
649 653
@@ -1132,6 +1136,8 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
1132 gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); 1136 gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
1133 rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); 1137 rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK);
1134 rgd->rd_free_clone = rgd->rd_free; 1138 rgd->rd_free_clone = rgd->rd_free;
1139 /* max out the rgrp allocation failure point */
1140 rgd->rd_extfail_pt = rgd->rd_free;
1135 } 1141 }
1136 if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) { 1142 if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) {
1137 rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd)); 1143 rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd));
@@ -1593,6 +1599,8 @@ fail:
1593 * Side effects: 1599 * Side effects:
1594 * - If looking for free blocks, we set GBF_FULL on each bitmap which 1600 * - If looking for free blocks, we set GBF_FULL on each bitmap which
1595 * has no free blocks in it. 1601 * has no free blocks in it.
1602 * - If looking for free blocks, we set rd_extfail_pt on each rgrp which
1603 * has come up short on a free block search.
1596 * 1604 *
1597 * Returns: 0 on success, -ENOSPC if there is no block of the requested state 1605 * Returns: 0 on success, -ENOSPC if there is no block of the requested state
1598 */ 1606 */
@@ -1604,6 +1612,8 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
1604 struct buffer_head *bh; 1612 struct buffer_head *bh;
1605 int initial_bii; 1613 int initial_bii;
1606 u32 initial_offset; 1614 u32 initial_offset;
1615 int first_bii = rbm->bii;
1616 u32 first_offset = rbm->offset;
1607 u32 offset; 1617 u32 offset;
1608 u8 *buffer; 1618 u8 *buffer;
1609 int n = 0; 1619 int n = 0;
@@ -1679,6 +1689,13 @@ next_iter:
1679 if (minext == NULL || state != GFS2_BLKST_FREE) 1689 if (minext == NULL || state != GFS2_BLKST_FREE)
1680 return -ENOSPC; 1690 return -ENOSPC;
1681 1691
1692 /* If the extent was too small, and it's smaller than the smallest
1693 to have failed before, remember for future reference that it's
1694 useless to search this rgrp again for this amount or more. */
1695 if ((first_offset == 0) && (first_bii == 0) &&
1696 (*minext < rbm->rgd->rd_extfail_pt))
1697 rbm->rgd->rd_extfail_pt = *minext;
1698
1682 /* If the maximum extent we found is big enough to fulfill the 1699 /* If the maximum extent we found is big enough to fulfill the
1683 minimum requirements, use it anyway. */ 1700 minimum requirements, use it anyway. */
1684 if (maxext.len) { 1701 if (maxext.len) {
@@ -1924,7 +1941,9 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
1924 } 1941 }
1925 1942
1926 /* Skip unuseable resource groups */ 1943 /* Skip unuseable resource groups */
1927 if (rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) 1944 if ((rs->rs_rbm.rgd->rd_flags & (GFS2_RGF_NOALLOC |
1945 GFS2_RDF_ERROR)) ||
1946 (ap && (ap->target > rs->rs_rbm.rgd->rd_extfail_pt)))
1928 goto skip_rgrp; 1947 goto skip_rgrp;
1929 1948
1930 if (sdp->sd_args.ar_rgrplvb) 1949 if (sdp->sd_args.ar_rgrplvb)
@@ -2106,10 +2125,10 @@ int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl)
2106 2125
2107 if (rgd == NULL) 2126 if (rgd == NULL)
2108 return 0; 2127 return 0;
2109 gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u\n", 2128 gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u r:%u e:%u\n",
2110 (unsigned long long)rgd->rd_addr, rgd->rd_flags, 2129 (unsigned long long)rgd->rd_addr, rgd->rd_flags,
2111 rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes, 2130 rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes,
2112 rgd->rd_reserved); 2131 rgd->rd_reserved, rgd->rd_extfail_pt);
2113 spin_lock(&rgd->rd_rsspin); 2132 spin_lock(&rgd->rd_rsspin);
2114 for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) { 2133 for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) {
2115 trs = rb_entry(n, struct gfs2_blkreserv, rs_node); 2134 trs = rb_entry(n, struct gfs2_blkreserv, rs_node);
@@ -2228,9 +2247,10 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
2228 2247
2229 /* Since all blocks are reserved in advance, this shouldn't happen */ 2248 /* Since all blocks are reserved in advance, this shouldn't happen */
2230 if (error) { 2249 if (error) {
2231 fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d\n", 2250 fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d fail_pt=%d\n",
2232 (unsigned long long)ip->i_no_addr, error, *nblocks, 2251 (unsigned long long)ip->i_no_addr, error, *nblocks,
2233 test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags)); 2252 test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags),
2253 rbm.rgd->rd_extfail_pt);
2234 goto rgrp_error; 2254 goto rgrp_error;
2235 } 2255 }
2236 2256