aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2012-07-31 10:21:20 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-09-24 05:46:56 -0400
commit4a993fb1503d11496974bd86c0b7123f63d9c8a2 (patch)
tree5d5d0da84412f95995cc6d1aa95d3bca1967f82c
parent71f890f7f758f340215d48fed5223f9cce05b652 (diff)
GFS2: Add structure to contain rgrp, bitmap, offset tuple
This patch introduces a new structure, gfs2_rbm, which is a tuple of a resource group, a bitmap within the resource group and an offset within that bitmap. This is designed to make manipulating these sets of variables easier. There is also a new helper function which converts this representation back to a disk block address. In addition, the rbtree nodes which are used for the reservations were not being correctly initialised, which is now fixed. Also, the tracing was not passing through the inode where it should have been. That is mostly fixed aside from one corner case. This needs to be revisited since there can also be a NULL rgrp in some cases which results in the device being incorrect in the trace. This is intended to be the first step towards cleaning up some of the allocation code, and some further bug fixes. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/bmap.c2
-rw-r--r--fs/gfs2/incore.h15
-rw-r--r--fs/gfs2/rgrp.c175
-rw-r--r--fs/gfs2/rgrp.h16
-rw-r--r--fs/gfs2/super.c2
-rw-r--r--fs/gfs2/trace_gfs2.h10
6 files changed, 105 insertions, 115 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 49cd7dd4a9f..1fd3ae237bd 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -786,7 +786,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
786 goto out_rlist; 786 goto out_rlist;
787 787
788 if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */ 788 if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */
789 gfs2_rs_deltree(ip->i_res); 789 gfs2_rs_deltree(ip, ip->i_res);
790 790
791 error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + 791 error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE +
792 RES_INDIRECT + RES_STATFS + RES_QUOTA, 792 RES_INDIRECT + RES_STATFS + RES_QUOTA,
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 52078a161ec..d5e254604c7 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -102,6 +102,17 @@ struct gfs2_rgrpd {
102 u32 rd_rs_cnt; /* count of current reservations */ 102 u32 rd_rs_cnt; /* count of current reservations */
103}; 103};
104 104
105struct gfs2_rbm {
106 struct gfs2_rgrpd *rgd;
107 struct gfs2_bitmap *bi; /* Bitmap must belong to the rgd */
108 u32 offset; /* The offset is bitmap relative */
109};
110
111static inline u64 gfs2_rbm_to_block(const struct gfs2_rbm *rbm)
112{
113 return rbm->rgd->rd_data0 + (rbm->bi->bi_start * GFS2_NBBY) + rbm->offset;
114}
115
105enum gfs2_state_bits { 116enum gfs2_state_bits {
106 BH_Pinned = BH_PrivateStart, 117 BH_Pinned = BH_PrivateStart,
107 BH_Escaped = BH_PrivateStart + 1, 118 BH_Escaped = BH_PrivateStart + 1,
@@ -251,13 +262,11 @@ struct gfs2_blkreserv {
251 atomic_t rs_sizehint; /* hint of the write size */ 262 atomic_t rs_sizehint; /* hint of the write size */
252 263
253 /* components used during get_local_rgrp (step 3): */ 264 /* components used during get_local_rgrp (step 3): */
254 struct gfs2_rgrpd *rs_rgd; /* pointer to the gfs2_rgrpd */ 265 struct gfs2_rbm rs_rbm;
255 struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */ 266 struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */
256 struct rb_node rs_node; /* link to other block reservations */ 267 struct rb_node rs_node; /* link to other block reservations */
257 268
258 /* components used during block searches and assignments (step 4): */ 269 /* components used during block searches and assignments (step 4): */
259 struct gfs2_bitmap *rs_bi; /* bitmap for the current allocation */
260 u32 rs_biblk; /* start block relative to the bi */
261 u32 rs_free; /* how many blocks are still free */ 270 u32 rs_free; /* how many blocks are still free */
262 271
263 /* ancillary quota stuff */ 272 /* ancillary quota stuff */
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index a2b43bb8349..eaa41885a00 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -192,7 +192,7 @@ static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state)
192 */ 192 */
193static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs) 193static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs)
194{ 194{
195 u64 startblk = gfs2_rs_startblk(rs); 195 u64 startblk = gfs2_rbm_to_block(&rs->rs_rbm);
196 196
197 if (blk >= startblk + rs->rs_free) 197 if (blk >= startblk + rs->rs_free)
198 return 1; 198 return 1;
@@ -487,6 +487,8 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
487 if (!res) 487 if (!res)
488 error = -ENOMEM; 488 error = -ENOMEM;
489 489
490 rb_init_node(&res->rs_node);
491
490 down_write(&ip->i_rw_mutex); 492 down_write(&ip->i_rw_mutex);
491 if (ip->i_res) 493 if (ip->i_res)
492 kmem_cache_free(gfs2_rsrv_cachep, res); 494 kmem_cache_free(gfs2_rsrv_cachep, res);
@@ -499,8 +501,8 @@ int gfs2_rs_alloc(struct gfs2_inode *ip)
499static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs) 501static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs)
500{ 502{
501 gfs2_print_dbg(seq, " r: %llu s:%llu b:%u f:%u\n", 503 gfs2_print_dbg(seq, " r: %llu s:%llu b:%u f:%u\n",
502 rs->rs_rgd->rd_addr, gfs2_rs_startblk(rs), rs->rs_biblk, 504 rs->rs_rbm.rgd->rd_addr, gfs2_rbm_to_block(&rs->rs_rbm),
503 rs->rs_free); 505 rs->rs_rbm.offset, rs->rs_free);
504} 506}
505 507
506/** 508/**
@@ -508,40 +510,28 @@ static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs)
508 * @rs: The reservation to remove 510 * @rs: The reservation to remove
509 * 511 *
510 */ 512 */
511static void __rs_deltree(struct gfs2_blkreserv *rs) 513static void __rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs)
512{ 514{
513 struct gfs2_rgrpd *rgd; 515 struct gfs2_rgrpd *rgd;
514 516
515 if (!gfs2_rs_active(rs)) 517 if (!gfs2_rs_active(rs))
516 return; 518 return;
517 519
518 rgd = rs->rs_rgd; 520 rgd = rs->rs_rbm.rgd;
519 /* We can't do this: The reason is that when the rgrp is invalidated, 521 trace_gfs2_rs(ip, rs, TRACE_RS_TREEDEL);
520 it's in the "middle" of acquiring the glock, but the HOLDER bit 522 rb_erase(&rs->rs_node, &rgd->rd_rstree);
521 isn't set yet: 523 rb_init_node(&rs->rs_node);
522 BUG_ON(!gfs2_glock_is_locked_by_me(rs->rs_rgd->rd_gl));*/
523 trace_gfs2_rs(NULL, rs, TRACE_RS_TREEDEL);
524
525 if (!RB_EMPTY_ROOT(&rgd->rd_rstree))
526 rb_erase(&rs->rs_node, &rgd->rd_rstree);
527 BUG_ON(!rgd->rd_rs_cnt); 524 BUG_ON(!rgd->rd_rs_cnt);
528 rgd->rd_rs_cnt--; 525 rgd->rd_rs_cnt--;
529 526
530 if (rs->rs_free) { 527 if (rs->rs_free) {
531 /* return reserved blocks to the rgrp and the ip */ 528 /* return reserved blocks to the rgrp and the ip */
532 BUG_ON(rs->rs_rgd->rd_reserved < rs->rs_free); 529 BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free);
533 rs->rs_rgd->rd_reserved -= rs->rs_free; 530 rs->rs_rbm.rgd->rd_reserved -= rs->rs_free;
534 rs->rs_free = 0; 531 rs->rs_free = 0;
535 clear_bit(GBF_FULL, &rs->rs_bi->bi_flags); 532 clear_bit(GBF_FULL, &rs->rs_rbm.bi->bi_flags);
536 smp_mb__after_clear_bit(); 533 smp_mb__after_clear_bit();
537 } 534 }
538 /* We can't change any of the step 1 or step 2 components of the rs.
539 E.g. We can't set rs_rgd to NULL because the rgd glock is held and
540 dequeued through this pointer.
541 Can't: atomic_set(&rs->rs_sizehint, 0);
542 Can't: rs->rs_rgd = NULL;*/
543 rs->rs_bi = NULL;
544 rs->rs_biblk = 0;
545} 535}
546 536
547/** 537/**
@@ -549,17 +539,16 @@ static void __rs_deltree(struct gfs2_blkreserv *rs)
549 * @rs: The reservation to remove 539 * @rs: The reservation to remove
550 * 540 *
551 */ 541 */
552void gfs2_rs_deltree(struct gfs2_blkreserv *rs) 542void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs)
553{ 543{
554 struct gfs2_rgrpd *rgd; 544 struct gfs2_rgrpd *rgd;
555 545
556 if (!gfs2_rs_active(rs)) 546 rgd = rs->rs_rbm.rgd;
557 return; 547 if (rgd) {
558 548 spin_lock(&rgd->rd_rsspin);
559 rgd = rs->rs_rgd; 549 __rs_deltree(ip, rs);
560 spin_lock(&rgd->rd_rsspin); 550 spin_unlock(&rgd->rd_rsspin);
561 __rs_deltree(rs); 551 }
562 spin_unlock(&rgd->rd_rsspin);
563} 552}
564 553
565/** 554/**
@@ -571,7 +560,7 @@ void gfs2_rs_delete(struct gfs2_inode *ip)
571{ 560{
572 down_write(&ip->i_rw_mutex); 561 down_write(&ip->i_rw_mutex);
573 if (ip->i_res) { 562 if (ip->i_res) {
574 gfs2_rs_deltree(ip->i_res); 563 gfs2_rs_deltree(ip, ip->i_res);
575 trace_gfs2_rs(ip, ip->i_res, TRACE_RS_DELETE); 564 trace_gfs2_rs(ip, ip->i_res, TRACE_RS_DELETE);
576 BUG_ON(ip->i_res->rs_free); 565 BUG_ON(ip->i_res->rs_free);
577 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); 566 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
@@ -596,7 +585,7 @@ static void return_all_reservations(struct gfs2_rgrpd *rgd)
596 spin_lock(&rgd->rd_rsspin); 585 spin_lock(&rgd->rd_rsspin);
597 while ((n = rb_first(&rgd->rd_rstree))) { 586 while ((n = rb_first(&rgd->rd_rstree))) {
598 rs = rb_entry(n, struct gfs2_blkreserv, rs_node); 587 rs = rb_entry(n, struct gfs2_blkreserv, rs_node);
599 __rs_deltree(rs); 588 __rs_deltree(NULL, rs);
600 } 589 }
601 spin_unlock(&rgd->rd_rsspin); 590 spin_unlock(&rgd->rd_rsspin);
602} 591}
@@ -1284,7 +1273,7 @@ static struct gfs2_blkreserv *rs_insert(struct gfs2_bitmap *bi,
1284 struct rb_node **newn, *parent = NULL; 1273 struct rb_node **newn, *parent = NULL;
1285 int rc; 1274 int rc;
1286 struct gfs2_blkreserv *rs = ip->i_res; 1275 struct gfs2_blkreserv *rs = ip->i_res;
1287 struct gfs2_rgrpd *rgd = rs->rs_rgd; 1276 struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd;
1288 u64 fsblock = gfs2_bi2rgd_blk(bi, biblk) + rgd->rd_data0; 1277 u64 fsblock = gfs2_bi2rgd_blk(bi, biblk) + rgd->rd_data0;
1289 1278
1290 spin_lock(&rgd->rd_rsspin); 1279 spin_lock(&rgd->rd_rsspin);
@@ -1312,8 +1301,8 @@ static struct gfs2_blkreserv *rs_insert(struct gfs2_bitmap *bi,
1312 /* Do our reservation work */ 1301 /* Do our reservation work */
1313 rs = ip->i_res; 1302 rs = ip->i_res;
1314 rs->rs_free = amount; 1303 rs->rs_free = amount;
1315 rs->rs_biblk = biblk; 1304 rs->rs_rbm.offset = biblk;
1316 rs->rs_bi = bi; 1305 rs->rs_rbm.bi = bi;
1317 rb_link_node(&rs->rs_node, parent, newn); 1306 rb_link_node(&rs->rs_node, parent, newn);
1318 rb_insert_color(&rs->rs_node, &rgd->rd_rstree); 1307 rb_insert_color(&rs->rs_node, &rgd->rd_rstree);
1319 1308
@@ -1564,34 +1553,34 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1564 goto out; 1553 goto out;
1565 } 1554 }
1566 if (gfs2_rs_active(rs)) { 1555 if (gfs2_rs_active(rs)) {
1567 begin = rs->rs_rgd; 1556 begin = rs->rs_rbm.rgd;
1568 flags = 0; /* Yoda: Do or do not. There is no try */ 1557 flags = 0; /* Yoda: Do or do not. There is no try */
1569 } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) { 1558 } else if (ip->i_rgd && rgrp_contains_block(ip->i_rgd, ip->i_goal)) {
1570 rs->rs_rgd = begin = ip->i_rgd; 1559 rs->rs_rbm.rgd = begin = ip->i_rgd;
1571 } else { 1560 } else {
1572 rs->rs_rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); 1561 rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
1573 } 1562 }
1574 if (rs->rs_rgd == NULL) 1563 if (rs->rs_rbm.rgd == NULL)
1575 return -EBADSLT; 1564 return -EBADSLT;
1576 1565
1577 while (loops < 3) { 1566 while (loops < 3) {
1578 rg_locked = 0; 1567 rg_locked = 0;
1579 1568
1580 if (gfs2_glock_is_locked_by_me(rs->rs_rgd->rd_gl)) { 1569 if (gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) {
1581 rg_locked = 1; 1570 rg_locked = 1;
1582 error = 0; 1571 error = 0;
1583 } else if (!loops && !gfs2_rs_active(rs) && 1572 } else if (!loops && !gfs2_rs_active(rs) &&
1584 rs->rs_rgd->rd_rs_cnt > RGRP_RSRV_MAX_CONTENDERS) { 1573 rs->rs_rbm.rgd->rd_rs_cnt > RGRP_RSRV_MAX_CONTENDERS) {
1585 /* If the rgrp already is maxed out for contenders, 1574 /* If the rgrp already is maxed out for contenders,
1586 we can eliminate it as a "first pass" without even 1575 we can eliminate it as a "first pass" without even
1587 requesting the rgrp glock. */ 1576 requesting the rgrp glock. */
1588 error = GLR_TRYFAILED; 1577 error = GLR_TRYFAILED;
1589 } else { 1578 } else {
1590 error = gfs2_glock_nq_init(rs->rs_rgd->rd_gl, 1579 error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl,
1591 LM_ST_EXCLUSIVE, flags, 1580 LM_ST_EXCLUSIVE, flags,
1592 &rs->rs_rgd_gh); 1581 &rs->rs_rgd_gh);
1593 if (!error && sdp->sd_args.ar_rgrplvb) { 1582 if (!error && sdp->sd_args.ar_rgrplvb) {
1594 error = update_rgrp_lvb(rs->rs_rgd); 1583 error = update_rgrp_lvb(rs->rs_rbm.rgd);
1595 if (error) { 1584 if (error) {
1596 gfs2_glock_dq_uninit(&rs->rs_rgd_gh); 1585 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1597 return error; 1586 return error;
@@ -1601,36 +1590,36 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1601 switch (error) { 1590 switch (error) {
1602 case 0: 1591 case 0:
1603 if (gfs2_rs_active(rs)) { 1592 if (gfs2_rs_active(rs)) {
1604 if (unclaimed_blocks(rs->rs_rgd) + 1593 if (unclaimed_blocks(rs->rs_rbm.rgd) +
1605 rs->rs_free >= requested) { 1594 rs->rs_free >= requested) {
1606 ip->i_rgd = rs->rs_rgd; 1595 ip->i_rgd = rs->rs_rbm.rgd;
1607 return 0; 1596 return 0;
1608 } 1597 }
1609 /* We have a multi-block reservation, but the 1598 /* We have a multi-block reservation, but the
1610 rgrp doesn't have enough free blocks to 1599 rgrp doesn't have enough free blocks to
1611 satisfy the request. Free the reservation 1600 satisfy the request. Free the reservation
1612 and look for a suitable rgrp. */ 1601 and look for a suitable rgrp. */
1613 gfs2_rs_deltree(rs); 1602 gfs2_rs_deltree(ip, rs);
1614 } 1603 }
1615 if (try_rgrp_fit(rs->rs_rgd, ip, requested)) { 1604 if (try_rgrp_fit(rs->rs_rbm.rgd, ip, requested)) {
1616 if (sdp->sd_args.ar_rgrplvb) 1605 if (sdp->sd_args.ar_rgrplvb)
1617 gfs2_rgrp_bh_get(rs->rs_rgd); 1606 gfs2_rgrp_bh_get(rs->rs_rbm.rgd);
1618 ip->i_rgd = rs->rs_rgd; 1607 ip->i_rgd = rs->rs_rbm.rgd;
1619 return 0; 1608 return 0;
1620 } 1609 }
1621 if (rs->rs_rgd->rd_flags & GFS2_RDF_CHECK) { 1610 if (rs->rs_rbm.rgd->rd_flags & GFS2_RDF_CHECK) {
1622 if (sdp->sd_args.ar_rgrplvb) 1611 if (sdp->sd_args.ar_rgrplvb)
1623 gfs2_rgrp_bh_get(rs->rs_rgd); 1612 gfs2_rgrp_bh_get(rs->rs_rbm.rgd);
1624 try_rgrp_unlink(rs->rs_rgd, &last_unlinked, 1613 try_rgrp_unlink(rs->rs_rbm.rgd, &last_unlinked,
1625 ip->i_no_addr); 1614 ip->i_no_addr);
1626 } 1615 }
1627 if (!rg_locked) 1616 if (!rg_locked)
1628 gfs2_glock_dq_uninit(&rs->rs_rgd_gh); 1617 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1629 /* fall through */ 1618 /* fall through */
1630 case GLR_TRYFAILED: 1619 case GLR_TRYFAILED:
1631 rs->rs_rgd = gfs2_rgrpd_get_next(rs->rs_rgd); 1620 rs->rs_rbm.rgd = gfs2_rgrpd_get_next(rs->rs_rbm.rgd);
1632 rs->rs_rgd = rs->rs_rgd ? : begin; /* if NULL, wrap */ 1621 rs->rs_rbm.rgd = rs->rs_rbm.rgd ? : begin; /* if NULL, wrap */
1633 if (rs->rs_rgd != begin) /* If we didn't wrap */ 1622 if (rs->rs_rbm.rgd != begin) /* If we didn't wrap */
1634 break; 1623 break;
1635 1624
1636 flags &= ~LM_FLAG_TRY; 1625 flags &= ~LM_FLAG_TRY;
@@ -1776,11 +1765,11 @@ do_search:
1776 if (rs == NULL) 1765 if (rs == NULL)
1777 break; 1766 break;
1778 1767
1779 BUG_ON(rs->rs_bi != bi); 1768 BUG_ON(rs->rs_rbm.bi != bi);
1780 biblk = BFITNOENT; 1769 biblk = BFITNOENT;
1781 /* This should jump to the first block after the 1770 /* This should jump to the first block after the
1782 reservation. */ 1771 reservation. */
1783 goal = rs->rs_biblk + rs->rs_free; 1772 goal = rs->rs_rbm.offset + rs->rs_free;
1784 if (goal >= bi->bi_len * GFS2_NBBY) 1773 if (goal >= bi->bi_len * GFS2_NBBY)
1785 break; 1774 break;
1786 } 1775 }
@@ -1805,9 +1794,7 @@ skip:
1805 1794
1806/** 1795/**
1807 * gfs2_alloc_extent - allocate an extent from a given bitmap 1796 * gfs2_alloc_extent - allocate an extent from a given bitmap
1808 * @rgd: the resource group descriptor 1797 * @rbm: the resource group information
1809 * @bi: the bitmap within the rgrp
1810 * @blk: the block within the bitmap
1811 * @dinode: TRUE if the first block we allocate is for a dinode 1798 * @dinode: TRUE if the first block we allocate is for a dinode
1812 * @n: The extent length 1799 * @n: The extent length
1813 * 1800 *
@@ -1815,9 +1802,12 @@ skip:
1815 * Set the found bits to @new_state to change block's allocation state. 1802 * Set the found bits to @new_state to change block's allocation state.
1816 * Returns: starting block number of the extent (fs scope) 1803 * Returns: starting block number of the extent (fs scope)
1817 */ 1804 */
1818static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, 1805static u64 gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode,
1819 u32 blk, bool dinode, unsigned int *n) 1806 unsigned int *n)
1820{ 1807{
1808 struct gfs2_rgrpd *rgd = rbm->rgd;
1809 struct gfs2_bitmap *bi = rbm->bi;
1810 u32 blk = rbm->offset;
1821 const unsigned int elen = *n; 1811 const unsigned int elen = *n;
1822 u32 goal, rgblk; 1812 u32 goal, rgblk;
1823 const u8 *buffer = NULL; 1813 const u8 *buffer = NULL;
@@ -1956,21 +1946,21 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode,
1956 unsigned int *nblocks) 1946 unsigned int *nblocks)
1957{ 1947{
1958 struct gfs2_blkreserv *rs = ip->i_res; 1948 struct gfs2_blkreserv *rs = ip->i_res;
1959 struct gfs2_rgrpd *rgd = rs->rs_rgd; 1949 struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd;
1960 struct gfs2_bitmap *bi; 1950 struct gfs2_bitmap *bi;
1961 u64 start_block = gfs2_rs_startblk(rs); 1951 u64 start_block = gfs2_rbm_to_block(&rs->rs_rbm);
1962 const unsigned int elen = *nblocks; 1952 const unsigned int elen = *nblocks;
1963 1953
1964 bi = rs->rs_bi; 1954 bi = rs->rs_rbm.bi;
1965 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); 1955 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
1966 1956
1967 for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { 1957 for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) {
1968 if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, 1958 if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
1969 bi->bi_len, rs->rs_biblk) != GFS2_BLKST_FREE) 1959 bi->bi_len, rs->rs_rbm.offset) != GFS2_BLKST_FREE)
1970 break; 1960 break;
1971 gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, 1961 gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_rbm.offset,
1972 dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); 1962 dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
1973 rs->rs_biblk++; 1963 rs->rs_rbm.offset++;
1974 rs->rs_free--; 1964 rs->rs_free--;
1975 1965
1976 BUG_ON(!rgd->rd_reserved); 1966 BUG_ON(!rgd->rd_reserved);
@@ -1980,7 +1970,7 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode,
1980 1970
1981 trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); 1971 trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM);
1982 if (!rs->rs_free || *nblocks != elen) 1972 if (!rs->rs_free || *nblocks != elen)
1983 gfs2_rs_deltree(rs); 1973 gfs2_rs_deltree(ip, rs);
1984 1974
1985 return start_block; 1975 return start_block;
1986} 1976}
@@ -2001,40 +1991,37 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
2001{ 1991{
2002 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1992 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2003 struct buffer_head *dibh; 1993 struct buffer_head *dibh;
2004 struct gfs2_rgrpd *rgd; 1994 struct gfs2_rbm rbm = { .rgd = ip->i_rgd, };
2005 unsigned int ndata; 1995 unsigned int ndata;
2006 u32 goal, blk; /* block, within the rgrp scope */ 1996 u32 goal; /* block, within the rgrp scope */
2007 u64 block; /* block, within the file system scope */ 1997 u64 block; /* block, within the file system scope */
2008 int error; 1998 int error;
2009 struct gfs2_bitmap *bi;
2010 1999
2011 /* If we have a reservation, claim blocks from it. */ 2000 /* If we have a reservation, claim blocks from it. */
2012 if (gfs2_rs_active(ip->i_res)) { 2001 if (gfs2_rs_active(ip->i_res)) {
2013 BUG_ON(!ip->i_res->rs_free); 2002 BUG_ON(!ip->i_res->rs_free);
2014 rgd = ip->i_res->rs_rgd; 2003 rbm.rgd = ip->i_res->rs_rbm.rgd;
2015 block = claim_reserved_blks(ip, dinode, nblocks); 2004 block = claim_reserved_blks(ip, dinode, nblocks);
2016 if (*nblocks) 2005 if (*nblocks)
2017 goto found_blocks; 2006 goto found_blocks;
2018 } 2007 }
2019 2008
2020 rgd = ip->i_rgd; 2009 if (!dinode && rgrp_contains_block(rbm.rgd, ip->i_goal))
2021 2010 goal = ip->i_goal - rbm.rgd->rd_data0;
2022 if (!dinode && rgrp_contains_block(rgd, ip->i_goal))
2023 goal = ip->i_goal - rgd->rd_data0;
2024 else 2011 else
2025 goal = rgd->rd_last_alloc; 2012 goal = rbm.rgd->rd_last_alloc;
2026 2013
2027 blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); 2014 rbm.offset = rgblk_search(rbm.rgd, goal, GFS2_BLKST_FREE, &rbm.bi);
2028 2015
2029 /* Since all blocks are reserved in advance, this shouldn't happen */ 2016 /* Since all blocks are reserved in advance, this shouldn't happen */
2030 if (blk == BFITNOENT) { 2017 if (rbm.offset == BFITNOENT) {
2031 printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); 2018 printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks);
2032 printk(KERN_WARNING "FULL=%d\n", 2019 printk(KERN_WARNING "FULL=%d\n",
2033 test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); 2020 test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags));
2034 goto rgrp_error; 2021 goto rgrp_error;
2035 } 2022 }
2036 2023
2037 block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); 2024 block = gfs2_alloc_extent(&rbm, dinode, nblocks);
2038found_blocks: 2025found_blocks:
2039 ndata = *nblocks; 2026 ndata = *nblocks;
2040 if (dinode) 2027 if (dinode)
@@ -2052,22 +2039,22 @@ found_blocks:
2052 brelse(dibh); 2039 brelse(dibh);
2053 } 2040 }
2054 } 2041 }
2055 if (rgd->rd_free < *nblocks) { 2042 if (rbm.rgd->rd_free < *nblocks) {
2056 printk(KERN_WARNING "nblocks=%u\n", *nblocks); 2043 printk(KERN_WARNING "nblocks=%u\n", *nblocks);
2057 goto rgrp_error; 2044 goto rgrp_error;
2058 } 2045 }
2059 2046
2060 rgd->rd_free -= *nblocks; 2047 rbm.rgd->rd_free -= *nblocks;
2061 if (dinode) { 2048 if (dinode) {
2062 rgd->rd_dinodes++; 2049 rbm.rgd->rd_dinodes++;
2063 *generation = rgd->rd_igeneration++; 2050 *generation = rbm.rgd->rd_igeneration++;
2064 if (*generation == 0) 2051 if (*generation == 0)
2065 *generation = rgd->rd_igeneration++; 2052 *generation = rbm.rgd->rd_igeneration++;
2066 } 2053 }
2067 2054
2068 gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); 2055 gfs2_trans_add_bh(rbm.rgd->rd_gl, rbm.rgd->rd_bits[0].bi_bh, 1);
2069 gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); 2056 gfs2_rgrp_out(rbm.rgd, rbm.rgd->rd_bits[0].bi_bh->b_data);
2070 gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, rgd->rd_bits[0].bi_bh->b_data); 2057 gfs2_rgrp_ondisk2lvb(rbm.rgd->rd_rgl, rbm.rgd->rd_bits[0].bi_bh->b_data);
2071 2058
2072 gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); 2059 gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
2073 if (dinode) 2060 if (dinode)
@@ -2081,14 +2068,14 @@ found_blocks:
2081 gfs2_quota_change(ip, ndata, ip->i_inode.i_uid, 2068 gfs2_quota_change(ip, ndata, ip->i_inode.i_uid,
2082 ip->i_inode.i_gid); 2069 ip->i_inode.i_gid);
2083 2070
2084 rgd->rd_free_clone -= *nblocks; 2071 rbm.rgd->rd_free_clone -= *nblocks;
2085 trace_gfs2_block_alloc(ip, rgd, block, *nblocks, 2072 trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks,
2086 dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); 2073 dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
2087 *bn = block; 2074 *bn = block;
2088 return 0; 2075 return 0;
2089 2076
2090rgrp_error: 2077rgrp_error:
2091 gfs2_rgrp_error(rgd); 2078 gfs2_rgrp_error(rbm.rgd);
2092 return -EIO; 2079 return -EIO;
2093} 2080}
2094 2081
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 0b0e9cc7e3d..c98f6af07e1 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -46,7 +46,7 @@ extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
46 bool dinode, u64 *generation); 46 bool dinode, u64 *generation);
47 47
48extern int gfs2_rs_alloc(struct gfs2_inode *ip); 48extern int gfs2_rs_alloc(struct gfs2_inode *ip);
49extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); 49extern void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs);
50extern void gfs2_rs_delete(struct gfs2_inode *ip); 50extern void gfs2_rs_delete(struct gfs2_inode *ip);
51extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); 51extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta);
52extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); 52extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
@@ -73,22 +73,16 @@ extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
73 const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); 73 const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed);
74extern int gfs2_fitrim(struct file *filp, void __user *argp); 74extern int gfs2_fitrim(struct file *filp, void __user *argp);
75 75
76/* This is how to tell if a multi-block reservation is in the rgrp tree: */ 76/* This is how to tell if a reservation is in the rgrp tree: */
77static inline int gfs2_rs_active(struct gfs2_blkreserv *rs) 77static inline bool gfs2_rs_active(struct gfs2_blkreserv *rs)
78{ 78{
79 if (rs && rs->rs_bi) 79 return rs && !RB_EMPTY_NODE(&rs->rs_node);
80 return 1;
81 return 0;
82} 80}
83 81
82
84static inline u32 gfs2_bi2rgd_blk(const struct gfs2_bitmap *bi, u32 blk) 83static inline u32 gfs2_bi2rgd_blk(const struct gfs2_bitmap *bi, u32 blk)
85{ 84{
86 return (bi->bi_start * GFS2_NBBY) + blk; 85 return (bi->bi_start * GFS2_NBBY) + blk;
87} 86}
88 87
89static inline u64 gfs2_rs_startblk(const struct gfs2_blkreserv *rs)
90{
91 return gfs2_bi2rgd_blk(rs->rs_bi, rs->rs_biblk) + rs->rs_rgd->rd_data0;
92}
93
94#endif /* __RGRP_DOT_H__ */ 88#endif /* __RGRP_DOT_H__ */
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index fc3168f47a1..3cbac680303 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1557,7 +1557,7 @@ out_truncate:
1557out_unlock: 1557out_unlock:
1558 /* Error path for case 1 */ 1558 /* Error path for case 1 */
1559 if (gfs2_rs_active(ip->i_res)) 1559 if (gfs2_rs_active(ip->i_res))
1560 gfs2_rs_deltree(ip->i_res); 1560 gfs2_rs_deltree(ip, ip->i_res);
1561 1561
1562 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) 1562 if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags))
1563 gfs2_glock_dq(&ip->i_iopen_gh); 1563 gfs2_glock_dq(&ip->i_iopen_gh);
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h
index a25c252fe41..b947aa4dfca 100644
--- a/fs/gfs2/trace_gfs2.h
+++ b/fs/gfs2/trace_gfs2.h
@@ -526,12 +526,12 @@ TRACE_EVENT(gfs2_rs,
526 ), 526 ),
527 527
528 TP_fast_assign( 528 TP_fast_assign(
529 __entry->dev = rs->rs_rgd ? rs->rs_rgd->rd_sbd->sd_vfs->s_dev : 0; 529 __entry->dev = rs->rs_rbm.rgd ? rs->rs_rbm.rgd->rd_sbd->sd_vfs->s_dev : 0;
530 __entry->rd_addr = rs->rs_rgd ? rs->rs_rgd->rd_addr : 0; 530 __entry->rd_addr = rs->rs_rbm.rgd ? rs->rs_rbm.rgd->rd_addr : 0;
531 __entry->rd_free_clone = rs->rs_rgd ? rs->rs_rgd->rd_free_clone : 0; 531 __entry->rd_free_clone = rs->rs_rbm.rgd ? rs->rs_rbm.rgd->rd_free_clone : 0;
532 __entry->rd_reserved = rs->rs_rgd ? rs->rs_rgd->rd_reserved : 0; 532 __entry->rd_reserved = rs->rs_rbm.rgd ? rs->rs_rbm.rgd->rd_reserved : 0;
533 __entry->inum = ip ? ip->i_no_addr : 0; 533 __entry->inum = ip ? ip->i_no_addr : 0;
534 __entry->start = gfs2_rs_startblk(rs); 534 __entry->start = gfs2_rbm_to_block(&rs->rs_rbm);
535 __entry->free = rs->rs_free; 535 __entry->free = rs->rs_free;
536 __entry->func = func; 536 __entry->func = func;
537 ), 537 ),