diff options
author | Bob Peterson <rpeterso@redhat.com> | 2012-06-06 06:17:59 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2012-06-06 06:17:59 -0400 |
commit | 0a305e496059a113f93bdd3ad27a5aaa917fe34d (patch) | |
tree | b0b6ce3997fef4c4e28f598a98e2e08c939414a6 | |
parent | eea5b5510fc5545d15b69da8e485a7424ae388cf (diff) |
GFS2: Extend the life of the reservations
This patch lengthens the lifespan of the reservations structure for
inodes. Before, they were allocated and deallocated for every write
operation. With this patch, they are allocated when the first write
occurs, and deallocated when the last process closes the file.
It's more efficient to do it this way because it saves GFS2 a lot of
unnecessary allocates and frees. It also gives us more flexibility
for the future: (1) we can now fold the qadata structure back into
the structure and save those alloc/frees, (2) we can use this for
multi-block reservations.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r-- | fs/gfs2/aops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 23 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 23 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 13 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 68 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 10 | ||||
-rw-r--r-- | fs/gfs2/super.c | 2 | ||||
-rw-r--r-- | fs/gfs2/trans.h | 2 |
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); |
879 | failed: | 879 | failed: |
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); |
1610 | out_q: | 1618 | out_q: |
1611 | gfs2_glock_dq_uninit(&q_gh); | 1619 | gfs2_glock_dq_uninit(&q_gh); |
1612 | out_put: | 1620 | out_unlockput: |
1613 | mutex_unlock(&ip->i_inode.i_mutex); | 1621 | mutex_unlock(&ip->i_inode.i_mutex); |
1622 | out_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 | */ | ||
424 | int 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 | */ | ||
443 | void 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 | |||
420 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | 453 | void 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 | |||
1002 | static 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 | ||
1165 | static 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 | ||
1214 | out: | 1220 | out: |
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); | |||
43 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | 43 | extern 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 | ||
46 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | ||
47 | extern void gfs2_rs_delete(struct gfs2_inode *ip); | ||
46 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 48 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
47 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 49 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
48 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 50 | extern 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); |
69 | extern int gfs2_fitrim(struct file *filp, void __user *argp); | 71 | extern int gfs2_fitrim(struct file *filp, void __user *argp); |
70 | 72 | ||
73 | /* This is how to tell if a reservation is "inplace" reserved: */ | ||
74 | static 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: | |||
1554 | out: | 1554 | out: |
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; | |||
31 | static inline unsigned int gfs2_rg_blocks(const struct gfs2_inode *ip) | 31 | static 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 | } |