aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2012-07-30 09:53:19 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-09-24 05:46:54 -0400
commit71f890f7f758f340215d48fed5223f9cce05b652 (patch)
treee0a274e17e9a6e2a623fceaa47b9faf1635d7343 /fs/gfs2
parent1f981697432daea3c0abf938b39174dcfb29340e (diff)
GFS2: Remove rs_requested field from reservations
The rs_requested field is left over from the original allocation code, however this should have been a parameter passed to the various functions from gfs2_inplace_reserve() and not a member of the reservation structure as the value is not required after the initial allocation. This also helps simplify the code since we no longer need to set the rs_requested to zero. Also the gfs2_inplace_release() function can also be simplified since the reservation structure will always be defined when it is called, and the only remaining task is to unlock the rgrp if required. It can also now be called unconditionally too, resulting in a further simplification. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/aops.c9
-rw-r--r--fs/gfs2/file.c4
-rw-r--r--fs/gfs2/incore.h3
-rw-r--r--fs/gfs2/inode.c9
-rw-r--r--fs/gfs2/quota.c9
-rw-r--r--fs/gfs2/rgrp.c35
-rw-r--r--fs/gfs2/rgrp.h8
-rw-r--r--fs/gfs2/trans.h7
-rw-r--r--fs/gfs2/xattr.c2
9 files changed, 27 insertions, 59 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index d6526347d386..00eaa83871b7 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -612,6 +612,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
612 struct gfs2_sbd *sdp = GFS2_SB(mapping->host); 612 struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
613 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 613 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
614 unsigned int data_blocks = 0, ind_blocks = 0, rblocks; 614 unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
615 unsigned requested = 0;
615 int alloc_required; 616 int alloc_required;
616 int error = 0; 617 int error = 0;
617 pgoff_t index = pos >> PAGE_CACHE_SHIFT; 618 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
@@ -641,7 +642,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
641 if (error) 642 if (error)
642 goto out_unlock; 643 goto out_unlock;
643 644
644 error = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); 645 requested = data_blocks + ind_blocks;
646 error = gfs2_inplace_reserve(ip, requested);
645 if (error) 647 if (error)
646 goto out_qunlock; 648 goto out_qunlock;
647 } 649 }
@@ -654,7 +656,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
654 if (&ip->i_inode == sdp->sd_rindex) 656 if (&ip->i_inode == sdp->sd_rindex)
655 rblocks += 2 * RES_STATFS; 657 rblocks += 2 * RES_STATFS;
656 if (alloc_required) 658 if (alloc_required)
657 rblocks += gfs2_rg_blocks(ip); 659 rblocks += gfs2_rg_blocks(ip, requested);
658 660
659 error = gfs2_trans_begin(sdp, rblocks, 661 error = gfs2_trans_begin(sdp, rblocks,
660 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); 662 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize);
@@ -868,8 +870,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
868 brelse(dibh); 870 brelse(dibh);
869failed: 871failed:
870 gfs2_trans_end(sdp); 872 gfs2_trans_end(sdp);
871 if (gfs2_mb_reserved(ip)) 873 gfs2_inplace_release(ip);
872 gfs2_inplace_release(ip);
873 if (ip->i_res->rs_qa_qd_num) 874 if (ip->i_res->rs_qa_qd_num)
874 gfs2_quota_unlock(ip); 875 gfs2_quota_unlock(ip);
875 if (inode == sdp->sd_rindex) { 876 if (inode == sdp->sd_rindex) {
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 382000ffac1f..30e21997a1a1 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -441,7 +441,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
441 rblocks += data_blocks ? data_blocks : 1; 441 rblocks += data_blocks ? data_blocks : 1;
442 if (ind_blocks || data_blocks) { 442 if (ind_blocks || data_blocks) {
443 rblocks += RES_STATFS + RES_QUOTA; 443 rblocks += RES_STATFS + RES_QUOTA;
444 rblocks += gfs2_rg_blocks(ip); 444 rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks);
445 } 445 }
446 ret = gfs2_trans_begin(sdp, rblocks, 0); 446 ret = gfs2_trans_begin(sdp, rblocks, 0);
447 if (ret) 447 if (ret)
@@ -845,7 +845,7 @@ retry:
845 &max_bytes, &data_blocks, &ind_blocks); 845 &max_bytes, &data_blocks, &ind_blocks);
846 846
847 rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + 847 rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
848 RES_RG_HDR + gfs2_rg_blocks(ip); 848 RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks);
849 if (gfs2_is_jdata(ip)) 849 if (gfs2_is_jdata(ip))
850 rblocks += data_blocks ? data_blocks : 1; 850 rblocks += data_blocks ? data_blocks : 1;
851 851
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index aaecc8085fc5..52078a161ecd 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -250,9 +250,6 @@ struct gfs2_blkreserv {
250 /* components used during write (step 1): */ 250 /* components used during write (step 1): */
251 atomic_t rs_sizehint; /* hint of the write size */ 251 atomic_t rs_sizehint; /* hint of the write size */
252 252
253 /* components used during inplace_reserve (step 2): */
254 u32 rs_requested; /* Filled in by caller of gfs2_inplace_reserve() */
255
256 /* components used during get_local_rgrp (step 3): */ 253 /* components used during get_local_rgrp (step 3): */
257 struct gfs2_rgrpd *rs_rgd; /* pointer to the gfs2_rgrpd */ 254 struct gfs2_rgrpd *rs_rgd; /* pointer to the gfs2_rgrpd */
258 struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */ 255 struct gfs2_holder rs_rgd_gh; /* Filled in by get_local_rgrp */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 753af3d86bbc..f2709ea887da 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -737,10 +737,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
737 brelse(bh); 737 brelse(bh);
738 738
739 gfs2_trans_end(sdp); 739 gfs2_trans_end(sdp);
740 /* Check if we reserved space in the rgrp. Function link_dinode may 740 gfs2_inplace_release(dip);
741 not, depending on whether alloc is required. */
742 if (gfs2_mb_reserved(dip))
743 gfs2_inplace_release(dip);
744 gfs2_quota_unlock(dip); 741 gfs2_quota_unlock(dip);
745 mark_inode_dirty(inode); 742 mark_inode_dirty(inode);
746 gfs2_glock_dq_uninit_m(2, ghs); 743 gfs2_glock_dq_uninit_m(2, ghs);
@@ -897,7 +894,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
897 goto out_gunlock_q; 894 goto out_gunlock_q;
898 895
899 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 896 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
900 gfs2_rg_blocks(dip) + 897 gfs2_rg_blocks(dip, sdp->sd_max_dirres) +
901 2 * RES_DINODE + RES_STATFS + 898 2 * RES_DINODE + RES_STATFS +
902 RES_QUOTA, 0); 899 RES_QUOTA, 0);
903 if (error) 900 if (error)
@@ -1378,7 +1375,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1378 goto out_gunlock_q; 1375 goto out_gunlock_q;
1379 1376
1380 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 1377 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
1381 gfs2_rg_blocks(ndip) + 1378 gfs2_rg_blocks(ndip, sdp->sd_max_dirres) +
1382 4 * RES_DINODE + 4 * RES_LEAF + 1379 4 * RES_DINODE + 4 * RES_LEAF +
1383 RES_STATFS + RES_QUOTA + 4, 0); 1380 RES_STATFS + RES_QUOTA + 4, 0);
1384 if (error) 1381 if (error)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index a3bde91645c2..420bc3805ccc 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -765,6 +765,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
765 struct gfs2_holder *ghs, i_gh; 765 struct gfs2_holder *ghs, i_gh;
766 unsigned int qx, x; 766 unsigned int qx, x;
767 struct gfs2_quota_data *qd; 767 struct gfs2_quota_data *qd;
768 unsigned reserved;
768 loff_t offset; 769 loff_t offset;
769 unsigned int nalloc = 0, blocks; 770 unsigned int nalloc = 0, blocks;
770 int error; 771 int error;
@@ -811,13 +812,13 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
811 * two blocks need to be updated instead of 1 */ 812 * two blocks need to be updated instead of 1 */
812 blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; 813 blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3;
813 814
814 error = gfs2_inplace_reserve(ip, 1 + 815 reserved = 1 + (nalloc * (data_blocks + ind_blocks));
815 (nalloc * (data_blocks + ind_blocks))); 816 error = gfs2_inplace_reserve(ip, reserved);
816 if (error) 817 if (error)
817 goto out_alloc; 818 goto out_alloc;
818 819
819 if (nalloc) 820 if (nalloc)
820 blocks += gfs2_rg_blocks(ip) + nalloc * ind_blocks + RES_STATFS; 821 blocks += gfs2_rg_blocks(ip, reserved) + nalloc * ind_blocks + RES_STATFS;
821 822
822 error = gfs2_trans_begin(sdp, blocks, 0); 823 error = gfs2_trans_begin(sdp, blocks, 0);
823 if (error) 824 if (error)
@@ -1598,7 +1599,7 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
1598 error = gfs2_inplace_reserve(ip, blocks); 1599 error = gfs2_inplace_reserve(ip, blocks);
1599 if (error) 1600 if (error)
1600 goto out_i; 1601 goto out_i;
1601 blocks += gfs2_rg_blocks(ip); 1602 blocks += gfs2_rg_blocks(ip, blocks);
1602 } 1603 }
1603 1604
1604 /* Some quotas span block boundaries and can update two blocks, 1605 /* Some quotas span block boundaries and can update two blocks,
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index c9ed814eeb6f..a2b43bb83499 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -539,7 +539,6 @@ static void __rs_deltree(struct gfs2_blkreserv *rs)
539 E.g. We can't set rs_rgd to NULL because the rgd glock is held and 539 E.g. We can't set rs_rgd to NULL because the rgd glock is held and
540 dequeued through this pointer. 540 dequeued through this pointer.
541 Can't: atomic_set(&rs->rs_sizehint, 0); 541 Can't: atomic_set(&rs->rs_sizehint, 0);
542 Can't: rs->rs_requested = 0;
543 Can't: rs->rs_rgd = NULL;*/ 542 Can't: rs->rs_rgd = NULL;*/
544 rs->rs_bi = NULL; 543 rs->rs_bi = NULL;
545 rs->rs_biblk = 0; 544 rs->rs_biblk = 0;
@@ -1350,7 +1349,7 @@ static u32 unclaimed_blocks(struct gfs2_rgrpd *rgd)
1350 * Returns: 0 if successful or BFITNOENT if there isn't enough free space 1349 * Returns: 0 if successful or BFITNOENT if there isn't enough free space
1351 */ 1350 */
1352 1351
1353static int rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) 1352static int rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, unsigned requested)
1354{ 1353{
1355 struct gfs2_bitmap *bi = rgd->rd_bits; 1354 struct gfs2_bitmap *bi = rgd->rd_bits;
1356 const u32 length = rgd->rd_length; 1355 const u32 length = rgd->rd_length;
@@ -1422,8 +1421,7 @@ do_search:
1422 what we can. If there's not enough, keep looking. */ 1421 what we can. If there's not enough, keep looking. */
1423 if (nonzero == NULL) 1422 if (nonzero == NULL)
1424 rsv_bytes = search_bytes; 1423 rsv_bytes = search_bytes;
1425 else if ((nonzero - ptr) * GFS2_NBBY >= 1424 else if ((nonzero - ptr) * GFS2_NBBY >= requested)
1426 ip->i_res->rs_requested)
1427 rsv_bytes = (nonzero - ptr); 1425 rsv_bytes = (nonzero - ptr);
1428 1426
1429 if (rsv_bytes) { 1427 if (rsv_bytes) {
@@ -1461,17 +1459,16 @@ skip:
1461 * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) 1459 * Returns: 1 on success (it fits), 0 on failure (it doesn't fit)
1462 */ 1460 */
1463 1461
1464static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) 1462static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
1463 unsigned requested)
1465{ 1464{
1466 struct gfs2_blkreserv *rs = ip->i_res;
1467
1468 if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) 1465 if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR))
1469 return 0; 1466 return 0;
1470 /* Look for a multi-block reservation. */ 1467 /* Look for a multi-block reservation. */
1471 if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS && 1468 if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS &&
1472 rg_mblk_search(rgd, ip) != BFITNOENT) 1469 rg_mblk_search(rgd, ip, requested) != BFITNOENT)
1473 return 1; 1470 return 1;
1474 if (unclaimed_blocks(rgd) >= rs->rs_requested) 1471 if (unclaimed_blocks(rgd) >= requested)
1475 return 1; 1472 return 1;
1476 1473
1477 return 0; 1474 return 0;
@@ -1562,7 +1559,6 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1562 1559
1563 if (sdp->sd_args.ar_rgrplvb) 1560 if (sdp->sd_args.ar_rgrplvb)
1564 flags |= GL_SKIP; 1561 flags |= GL_SKIP;
1565 rs->rs_requested = requested;
1566 if (gfs2_assert_warn(sdp, requested)) { 1562 if (gfs2_assert_warn(sdp, requested)) {
1567 error = -EINVAL; 1563 error = -EINVAL;
1568 goto out; 1564 goto out;
@@ -1606,7 +1602,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1606 case 0: 1602 case 0:
1607 if (gfs2_rs_active(rs)) { 1603 if (gfs2_rs_active(rs)) {
1608 if (unclaimed_blocks(rs->rs_rgd) + 1604 if (unclaimed_blocks(rs->rs_rgd) +
1609 rs->rs_free >= rs->rs_requested) { 1605 rs->rs_free >= requested) {
1610 ip->i_rgd = rs->rs_rgd; 1606 ip->i_rgd = rs->rs_rgd;
1611 return 0; 1607 return 0;
1612 } 1608 }
@@ -1616,7 +1612,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1616 and look for a suitable rgrp. */ 1612 and look for a suitable rgrp. */
1617 gfs2_rs_deltree(rs); 1613 gfs2_rs_deltree(rs);
1618 } 1614 }
1619 if (try_rgrp_fit(rs->rs_rgd, ip)) { 1615 if (try_rgrp_fit(rs->rs_rgd, ip, requested)) {
1620 if (sdp->sd_args.ar_rgrplvb) 1616 if (sdp->sd_args.ar_rgrplvb)
1621 gfs2_rgrp_bh_get(rs->rs_rgd); 1617 gfs2_rgrp_bh_get(rs->rs_rgd);
1622 ip->i_rgd = rs->rs_rgd; 1618 ip->i_rgd = rs->rs_rgd;
@@ -1656,8 +1652,6 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1656 error = -ENOSPC; 1652 error = -ENOSPC;
1657 1653
1658out: 1654out:
1659 if (error)
1660 rs->rs_requested = 0;
1661 return error; 1655 return error;
1662} 1656}
1663 1657
@@ -1672,15 +1666,8 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1672{ 1666{
1673 struct gfs2_blkreserv *rs = ip->i_res; 1667 struct gfs2_blkreserv *rs = ip->i_res;
1674 1668
1675 if (!rs)
1676 return;
1677
1678 if (!rs->rs_free)
1679 gfs2_rs_deltree(rs);
1680
1681 if (rs->rs_rgd_gh.gh_gl) 1669 if (rs->rs_rgd_gh.gh_gl)
1682 gfs2_glock_dq_uninit(&rs->rs_rgd_gh); 1670 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1683 rs->rs_requested = 0;
1684} 1671}
1685 1672
1686/** 1673/**
@@ -2021,12 +2008,6 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
2021 int error; 2008 int error;
2022 struct gfs2_bitmap *bi; 2009 struct gfs2_bitmap *bi;
2023 2010
2024 /* Only happens if there is a bug in gfs2, return something distinctive
2025 * to ensure that it is noticed.
2026 */
2027 if (ip->i_res->rs_requested == 0)
2028 return -ECANCELED;
2029
2030 /* If we have a reservation, claim blocks from it. */ 2011 /* If we have a reservation, claim blocks from it. */
2031 if (gfs2_rs_active(ip->i_res)) { 2012 if (gfs2_rs_active(ip->i_res)) {
2032 BUG_ON(!ip->i_res->rs_free); 2013 BUG_ON(!ip->i_res->rs_free);
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index ca6e26729b86..0b0e9cc7e3d9 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -73,14 +73,6 @@ 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 "inplace" reserved: */
77static inline int gfs2_mb_reserved(struct gfs2_inode *ip)
78{
79 if (ip->i_res && ip->i_res->rs_requested)
80 return 1;
81 return 0;
82}
83
84/* This is how to tell if a multi-block reservation is in the rgrp tree: */ 76/* This is how to tell if a multi-block reservation is in the rgrp tree: */
85static inline int gfs2_rs_active(struct gfs2_blkreserv *rs) 77static inline int gfs2_rs_active(struct gfs2_blkreserv *rs)
86{ 78{
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index 41f42cdccbb8..bf2ae9aeee7a 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
@@ -28,11 +28,10 @@ struct gfs2_glock;
28 28
29/* reserve either the number of blocks to be allocated plus the rg header 29/* reserve either the number of blocks to be allocated plus the rg header
30 * block, or all of the blocks in the rg, whichever is smaller */ 30 * block, or all of the blocks in the rg, whichever is smaller */
31static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) 31static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip, unsigned requested)
32{ 32{
33 const struct gfs2_blkreserv *rs = ip->i_res; 33 if (requested < ip->i_rgd->rd_length)
34 if (rs && rs->rs_requested < ip->i_rgd->rd_length) 34 return requested + 1;
35 return rs->rs_requested + 1;
36 return ip->i_rgd->rd_length; 35 return ip->i_rgd->rd_length;
37} 36}
38 37
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 5404ed1582ff..db330e5518cd 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -739,7 +739,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
739 goto out_gunlock_q; 739 goto out_gunlock_q;
740 740
741 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), 741 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
742 blks + gfs2_rg_blocks(ip) + 742 blks + gfs2_rg_blocks(ip, blks) +
743 RES_DINODE + RES_STATFS + RES_QUOTA, 0); 743 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
744 if (error) 744 if (error)
745 goto out_ipres; 745 goto out_ipres;