aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 d6526347d38..00eaa83871b 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 382000ffac1..30e21997a1a 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 aaecc8085fc..52078a161ec 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 753af3d86bb..f2709ea887d 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 a3bde91645c..420bc3805cc 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 c9ed814eeb6..a2b43bb8349 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 ca6e26729b8..0b0e9cc7e3d 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 41f42cdccbb..bf2ae9aeee7 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 5404ed1582f..db330e5518c 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;