aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/aops.c2
-rw-r--r--fs/gfs2/file.c23
-rw-r--r--fs/gfs2/inode.c23
-rw-r--r--fs/gfs2/quota.c13
-rw-r--r--fs/gfs2/rgrp.c68
-rw-r--r--fs/gfs2/rgrp.h10
-rw-r--r--fs/gfs2/super.c2
-rw-r--r--fs/gfs2/trans.h2
8 files changed, 104 insertions, 39 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index e80a464850c8..aba77b5720bc 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -878,7 +878,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
878 brelse(dibh); 878 brelse(dibh);
879failed: 879failed:
880 gfs2_trans_end(sdp); 880 gfs2_trans_end(sdp);
881 if (ip->i_res) 881 if (gfs2_mb_reserved(ip))
882 gfs2_inplace_release(ip); 882 gfs2_inplace_release(ip);
883 if (qa) { 883 if (qa) {
884 gfs2_quota_unlock(ip); 884 gfs2_quota_unlock(ip);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 31b199f6efc1..37906174d417 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -376,6 +376,10 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
376 */ 376 */
377 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 377 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
378 378
379 ret = gfs2_rs_alloc(ip);
380 if (ret)
381 return ret;
382
379 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); 383 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
380 ret = gfs2_glock_nq(&gh); 384 ret = gfs2_glock_nq(&gh);
381 if (ret) 385 if (ret)
@@ -569,10 +573,15 @@ static int gfs2_release(struct inode *inode, struct file *file)
569{ 573{
570 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; 574 struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
571 struct gfs2_file *fp; 575 struct gfs2_file *fp;
576 struct gfs2_inode *ip = GFS2_I(inode);
572 577
573 fp = file->private_data; 578 fp = file->private_data;
574 file->private_data = NULL; 579 file->private_data = NULL;
575 580
581 if ((file->f_mode & FMODE_WRITE) && ip->i_res &&
582 (atomic_read(&inode->i_writecount) == 1))
583 gfs2_rs_delete(ip);
584
576 if (gfs2_assert_warn(sdp, fp)) 585 if (gfs2_assert_warn(sdp, fp))
577 return -EIO; 586 return -EIO;
578 587
@@ -653,12 +662,16 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
653 unsigned long nr_segs, loff_t pos) 662 unsigned long nr_segs, loff_t pos)
654{ 663{
655 struct file *file = iocb->ki_filp; 664 struct file *file = iocb->ki_filp;
665 struct dentry *dentry = file->f_dentry;
666 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
667 int ret;
668
669 ret = gfs2_rs_alloc(ip);
670 if (ret)
671 return ret;
656 672
657 if (file->f_flags & O_APPEND) { 673 if (file->f_flags & O_APPEND) {
658 struct dentry *dentry = file->f_dentry;
659 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
660 struct gfs2_holder gh; 674 struct gfs2_holder gh;
661 int ret;
662 675
663 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); 676 ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
664 if (ret) 677 if (ret)
@@ -774,6 +787,10 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
774 if (bytes == 0) 787 if (bytes == 0)
775 bytes = sdp->sd_sb.sb_bsize; 788 bytes = sdp->sd_sb.sb_bsize;
776 789
790 error = gfs2_rs_alloc(ip);
791 if (error)
792 return error;
793
777 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); 794 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
778 error = gfs2_glock_nq(&ip->i_gh); 795 error = gfs2_glock_nq(&ip->i_gh);
779 if (unlikely(error)) 796 if (unlikely(error))
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a9ba2444e077..2a1b4b5a648c 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -667,6 +667,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
667 if (!name->len || name->len > GFS2_FNAMESIZE) 667 if (!name->len || name->len > GFS2_FNAMESIZE)
668 return -ENAMETOOLONG; 668 return -ENAMETOOLONG;
669 669
670 error = gfs2_rs_alloc(dip);
671 if (error)
672 return error;
673
670 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 674 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
671 if (error) 675 if (error)
672 goto fail; 676 goto fail;
@@ -704,6 +708,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
704 if (error) 708 if (error)
705 goto fail_gunlock2; 709 goto fail_gunlock2;
706 710
711 /* the new inode needs a reservation so it can allocate xattrs. */
712 error = gfs2_rs_alloc(GFS2_I(inode));
713 if (error)
714 goto fail_gunlock2;
715
707 error = gfs2_acl_create(dip, inode); 716 error = gfs2_acl_create(dip, inode);
708 if (error) 717 if (error)
709 goto fail_gunlock2; 718 goto fail_gunlock2;
@@ -722,7 +731,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
722 gfs2_trans_end(sdp); 731 gfs2_trans_end(sdp);
723 /* Check if we reserved space in the rgrp. Function link_dinode may 732 /* Check if we reserved space in the rgrp. Function link_dinode may
724 not, depending on whether alloc is required. */ 733 not, depending on whether alloc is required. */
725 if (dip->i_res) 734 if (gfs2_mb_reserved(dip))
726 gfs2_inplace_release(dip); 735 gfs2_inplace_release(dip);
727 gfs2_quota_unlock(dip); 736 gfs2_quota_unlock(dip);
728 gfs2_qadata_put(dip); 737 gfs2_qadata_put(dip);
@@ -819,6 +828,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
819 if (S_ISDIR(inode->i_mode)) 828 if (S_ISDIR(inode->i_mode))
820 return -EPERM; 829 return -EPERM;
821 830
831 error = gfs2_rs_alloc(dip);
832 if (error)
833 return error;
834
822 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); 835 gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
823 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); 836 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
824 837
@@ -1234,6 +1247,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
1234 if (error) 1247 if (error)
1235 return error; 1248 return error;
1236 1249
1250 error = gfs2_rs_alloc(ndip);
1251 if (error)
1252 return error;
1253
1237 if (odip != ndip) { 1254 if (odip != ndip) {
1238 error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 1255 error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
1239 0, &r_gh); 1256 0, &r_gh);
@@ -1644,6 +1661,10 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
1644 struct gfs2_holder i_gh; 1661 struct gfs2_holder i_gh;
1645 int error; 1662 int error;
1646 1663
1664 error = gfs2_rs_alloc(ip);
1665 if (error)
1666 return error;
1667
1647 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); 1668 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
1648 if (error) 1669 if (error)
1649 return error; 1670 return error;
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index b97178e7d397..197cc2dade7f 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -764,6 +764,10 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
764 unsigned int nalloc = 0, blocks; 764 unsigned int nalloc = 0, blocks;
765 int error; 765 int error;
766 766
767 error = gfs2_rs_alloc(ip);
768 if (error)
769 return error;
770
767 gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), 771 gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
768 &data_blocks, &ind_blocks); 772 &data_blocks, &ind_blocks);
769 773
@@ -1549,10 +1553,14 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
1549 if (error) 1553 if (error)
1550 return error; 1554 return error;
1551 1555
1556 error = gfs2_rs_alloc(ip);
1557 if (error)
1558 goto out_put;
1559
1552 mutex_lock(&ip->i_inode.i_mutex); 1560 mutex_lock(&ip->i_inode.i_mutex);
1553 error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh); 1561 error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh);
1554 if (error) 1562 if (error)
1555 goto out_put; 1563 goto out_unlockput;
1556 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); 1564 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
1557 if (error) 1565 if (error)
1558 goto out_q; 1566 goto out_q;
@@ -1609,8 +1617,9 @@ out_i:
1609 gfs2_glock_dq_uninit(&i_gh); 1617 gfs2_glock_dq_uninit(&i_gh);
1610out_q: 1618out_q:
1611 gfs2_glock_dq_uninit(&q_gh); 1619 gfs2_glock_dq_uninit(&q_gh);
1612out_put: 1620out_unlockput:
1613 mutex_unlock(&ip->i_inode.i_mutex); 1621 mutex_unlock(&ip->i_inode.i_mutex);
1622out_put:
1614 qd_put(qd); 1623 qd_put(qd);
1615 return error; 1624 return error;
1616} 1625}
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index f74fb9bd1973..e944fefbc9a8 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -417,6 +417,39 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd)
417 } 417 }
418} 418}
419 419
420/**
421 * gfs2_rs_alloc - make sure we have a reservation assigned to the inode
422 * @ip: the inode for this reservation
423 */
424int gfs2_rs_alloc(struct gfs2_inode *ip)
425{
426 int error = 0;
427
428 down_write(&ip->i_rw_mutex);
429 if (!ip->i_res) {
430 ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
431 if (!ip->i_res)
432 error = -ENOMEM;
433 }
434 up_write(&ip->i_rw_mutex);
435 return error;
436}
437
438/**
439 * gfs2_rs_delete - delete a reservation
440 * @ip: The inode for this reservation
441 *
442 */
443void gfs2_rs_delete(struct gfs2_inode *ip)
444{
445 down_write(&ip->i_rw_mutex);
446 if (ip->i_res) {
447 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
448 ip->i_res = NULL;
449 }
450 up_write(&ip->i_rw_mutex);
451}
452
420void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) 453void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
421{ 454{
422 struct rb_node *n; 455 struct rb_node *n;
@@ -993,22 +1026,6 @@ struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
993} 1026}
994 1027
995/** 1028/**
996 * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode
997 * @ip: the incore GFS2 inode structure
998 *
999 * Returns: the struct gfs2_qadata
1000 */
1001
1002static int gfs2_blkrsv_get(struct gfs2_inode *ip)
1003{
1004 BUG_ON(ip->i_res != NULL);
1005 ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS);
1006 if (!ip->i_res)
1007 return -ENOMEM;
1008 return 0;
1009}
1010
1011/**
1012 * try_rgrp_fit - See if a given reservation will fit in a given RG 1029 * try_rgrp_fit - See if a given reservation will fit in a given RG
1013 * @rgd: the RG data 1030 * @rgd: the RG data
1014 * @ip: the inode 1031 * @ip: the inode
@@ -1162,13 +1179,6 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1162 return -ENOSPC; 1179 return -ENOSPC;
1163} 1180}
1164 1181
1165static void gfs2_blkrsv_put(struct gfs2_inode *ip)
1166{
1167 BUG_ON(ip->i_res == NULL);
1168 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
1169 ip->i_res = NULL;
1170}
1171
1172/** 1182/**
1173 * gfs2_inplace_reserve - Reserve space in the filesystem 1183 * gfs2_inplace_reserve - Reserve space in the filesystem
1174 * @ip: the inode to reserve space for 1184 * @ip: the inode to reserve space for
@@ -1181,14 +1191,10 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1181{ 1191{
1182 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1192 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1183 struct gfs2_blkreserv *rs; 1193 struct gfs2_blkreserv *rs;
1184 int error; 1194 int error = 0;
1185 u64 last_unlinked = NO_BLOCK; 1195 u64 last_unlinked = NO_BLOCK;
1186 int tries = 0; 1196 int tries = 0;
1187 1197
1188 error = gfs2_blkrsv_get(ip);
1189 if (error)
1190 return error;
1191
1192 rs = ip->i_res; 1198 rs = ip->i_res;
1193 rs->rs_requested = requested; 1199 rs->rs_requested = requested;
1194 if (gfs2_assert_warn(sdp, requested)) { 1200 if (gfs2_assert_warn(sdp, requested)) {
@@ -1213,7 +1219,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1213 1219
1214out: 1220out:
1215 if (error) 1221 if (error)
1216 gfs2_blkrsv_put(ip); 1222 rs->rs_requested = 0;
1217 return error; 1223 return error;
1218} 1224}
1219 1225
@@ -1230,7 +1236,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
1230 1236
1231 if (rs->rs_rgd_gh.gh_gl) 1237 if (rs->rs_rgd_gh.gh_gl)
1232 gfs2_glock_dq_uninit(&rs->rs_rgd_gh); 1238 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1233 gfs2_blkrsv_put(ip); 1239 rs->rs_requested = 0;
1234} 1240}
1235 1241
1236/** 1242/**
@@ -1496,7 +1502,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
1496 /* Only happens if there is a bug in gfs2, return something distinctive 1502 /* Only happens if there is a bug in gfs2, return something distinctive
1497 * to ensure that it is noticed. 1503 * to ensure that it is noticed.
1498 */ 1504 */
1499 if (ip->i_res == NULL) 1505 if (ip->i_res->rs_requested == 0)
1500 return -ECANCELED; 1506 return -ECANCELED;
1501 1507
1502 rgd = ip->i_rgd; 1508 rgd = ip->i_rgd;
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index b4b10f4de25f..d9eda5f9ef2a 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -43,6 +43,8 @@ extern void gfs2_inplace_release(struct gfs2_inode *ip);
43extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, 43extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n,
44 bool dinode, u64 *generation); 44 bool dinode, u64 *generation);
45 45
46extern int gfs2_rs_alloc(struct gfs2_inode *ip);
47extern void gfs2_rs_delete(struct gfs2_inode *ip);
46extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); 48extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta);
47extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); 49extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
48extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); 50extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
@@ -68,4 +70,12 @@ extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
68 const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed); 70 const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed);
69extern int gfs2_fitrim(struct file *filp, void __user *argp); 71extern int gfs2_fitrim(struct file *filp, void __user *argp);
70 72
73/* This is how to tell if a reservation is "inplace" reserved: */
74static inline int gfs2_mb_reserved(struct gfs2_inode *ip)
75{
76 if (ip->i_res && ip->i_res->rs_requested)
77 return 1;
78 return 0;
79}
80
71#endif /* __RGRP_DOT_H__ */ 81#endif /* __RGRP_DOT_H__ */
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 713e621c240b..65578df29446 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1554,6 +1554,7 @@ out_unlock:
1554out: 1554out:
1555 /* Case 3 starts here */ 1555 /* Case 3 starts here */
1556 truncate_inode_pages(&inode->i_data, 0); 1556 truncate_inode_pages(&inode->i_data, 0);
1557 gfs2_rs_delete(ip);
1557 clear_inode(inode); 1558 clear_inode(inode);
1558 gfs2_dir_hash_inval(ip); 1559 gfs2_dir_hash_inval(ip);
1559 ip->i_gl->gl_object = NULL; 1560 ip->i_gl->gl_object = NULL;
@@ -1576,6 +1577,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
1576 ip->i_flags = 0; 1577 ip->i_flags = 0;
1577 ip->i_gl = NULL; 1578 ip->i_gl = NULL;
1578 ip->i_rgd = NULL; 1579 ip->i_rgd = NULL;
1580 ip->i_res = NULL;
1579 } 1581 }
1580 return &ip->i_inode; 1582 return &ip->i_inode;
1581} 1583}
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index 125d4572e1c0..41f42cdccbb8 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
@@ -31,7 +31,7 @@ struct gfs2_glock;
31static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) 31static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip)
32{ 32{
33 const struct gfs2_blkreserv *rs = ip->i_res; 33 const struct gfs2_blkreserv *rs = ip->i_res;
34 if (rs->rs_requested < ip->i_rgd->rd_length) 34 if (rs && rs->rs_requested < ip->i_rgd->rd_length)
35 return rs->rs_requested + 1; 35 return rs->rs_requested + 1;
36 return ip->i_rgd->rd_length; 36 return ip->i_rgd->rd_length;
37} 37}