diff options
-rw-r--r-- | fs/gfs2/bmap.c | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 15 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 175 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 16 | ||||
-rw-r--r-- | fs/gfs2/super.c | 2 | ||||
-rw-r--r-- | fs/gfs2/trace_gfs2.h | 10 |
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 | ||
105 | struct 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 | |||
111 | static 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 | |||
105 | enum gfs2_state_bits { | 116 | enum 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 | */ |
193 | static inline int rs_cmp(u64 blk, u32 len, struct gfs2_blkreserv *rs) | 193 | static 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) | |||
499 | static void dump_rs(struct seq_file *seq, struct gfs2_blkreserv *rs) | 501 | static 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 | */ |
511 | static void __rs_deltree(struct gfs2_blkreserv *rs) | 513 | static 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 | */ |
552 | void gfs2_rs_deltree(struct gfs2_blkreserv *rs) | 542 | void 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 | */ |
1818 | static u64 gfs2_alloc_extent(struct gfs2_rgrpd *rgd, struct gfs2_bitmap *bi, | 1805 | static 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); |
2038 | found_blocks: | 2025 | found_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 | ||
2090 | rgrp_error: | 2077 | rgrp_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 | ||
48 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | 48 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); |
49 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); | 49 | extern void gfs2_rs_deltree(struct gfs2_inode *ip, struct gfs2_blkreserv *rs); |
50 | extern void gfs2_rs_delete(struct gfs2_inode *ip); | 50 | extern void gfs2_rs_delete(struct gfs2_inode *ip); |
51 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 51 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
52 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 52 | extern 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); |
74 | extern int gfs2_fitrim(struct file *filp, void __user *argp); | 74 | extern 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: */ |
77 | static inline int gfs2_rs_active(struct gfs2_blkreserv *rs) | 77 | static 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 | |||
84 | static inline u32 gfs2_bi2rgd_blk(const struct gfs2_bitmap *bi, u32 blk) | 83 | static 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 | ||
89 | static 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: | |||
1557 | out_unlock: | 1557 | out_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 | ), |