aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2010-09-27 17:00:04 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2010-09-28 04:44:24 -0400
commitbf97b6734e027cc18abad420ab88f861f65d7816 (patch)
tree74892640ed482487f3bc630ad4fd20e62dec2c54 /fs
parentd0795f912318f65b800c6b619d749c3bf7c930fb (diff)
GFS2: reserve more blocks for transactions
Some of the functions in GFS2 were not reserving space in the transaction for the resource group header and the resource groups bitblocks that get added when you do allocation. GFS2 now makes sure to reserve space for the resource group header and either all the bitblocks in the resource group, or one for each block that it may allocate, whichever is smaller using the new gfs2_rg_blocks() inline function. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/aops.c2
-rw-r--r--fs/gfs2/bmap.c2
-rw-r--r--fs/gfs2/file.c4
-rw-r--r--fs/gfs2/ops_inode.c6
-rw-r--r--fs/gfs2/quota.c3
-rw-r--r--fs/gfs2/trans.h8
-rw-r--r--fs/gfs2/xattr.c2
7 files changed, 20 insertions, 7 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 180ef8a6de6..1bf178831ae 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -663,6 +663,8 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
663 rblocks += RES_STATFS + RES_QUOTA; 663 rblocks += RES_STATFS + RES_QUOTA;
664 if (&ip->i_inode == sdp->sd_rindex) 664 if (&ip->i_inode == sdp->sd_rindex)
665 rblocks += 2 * RES_STATFS; 665 rblocks += 2 * RES_STATFS;
666 if (alloc_required)
667 rblocks += gfs2_rg_blocks(al);
666 668
667 error = gfs2_trans_begin(sdp, rblocks, 669 error = gfs2_trans_begin(sdp, rblocks,
668 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize); 670 PAGE_CACHE_SIZE/sdp->sd_sb.sb_bsize);
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 04513e997df..5476c066d4e 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1151,7 +1151,7 @@ static int do_grow(struct inode *inode, u64 size)
1151 goto do_grow_qunlock; 1151 goto do_grow_qunlock;
1152 } 1152 }
1153 1153
1154 error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); 1154 error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT, 0);
1155 if (error) 1155 if (error)
1156 goto do_grow_release; 1156 goto do_grow_release;
1157 1157
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index daadcd2e755..237ee6a940d 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -382,8 +382,10 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
382 rblocks = RES_DINODE + ind_blocks; 382 rblocks = RES_DINODE + ind_blocks;
383 if (gfs2_is_jdata(ip)) 383 if (gfs2_is_jdata(ip))
384 rblocks += data_blocks ? data_blocks : 1; 384 rblocks += data_blocks ? data_blocks : 1;
385 if (ind_blocks || data_blocks) 385 if (ind_blocks || data_blocks) {
386 rblocks += RES_STATFS + RES_QUOTA; 386 rblocks += RES_STATFS + RES_QUOTA;
387 rblocks += gfs2_rg_blocks(al);
388 }
387 ret = gfs2_trans_begin(sdp, rblocks, 0); 389 ret = gfs2_trans_begin(sdp, rblocks, 0);
388 if (ret) 390 if (ret)
389 goto out_trans_fail; 391 goto out_trans_fail;
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 98a94cfc2bb..fba00171d91 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -219,7 +219,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
219 goto out_gunlock_q; 219 goto out_gunlock_q;
220 220
221 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 221 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
222 al->al_rgd->rd_length + 222 gfs2_rg_blocks(al) +
223 2 * RES_DINODE + RES_STATFS + 223 2 * RES_DINODE + RES_STATFS +
224 RES_QUOTA, 0); 224 RES_QUOTA, 0);
225 if (error) 225 if (error)
@@ -884,7 +884,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
884 goto out_gunlock_q; 884 goto out_gunlock_q;
885 885
886 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + 886 error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
887 al->al_rgd->rd_length + 887 gfs2_rg_blocks(al) +
888 4 * RES_DINODE + 4 * RES_LEAF + 888 4 * RES_DINODE + 4 * RES_LEAF +
889 RES_STATFS + RES_QUOTA + 4, 0); 889 RES_STATFS + RES_QUOTA + 4, 0);
890 if (error) 890 if (error)
@@ -1481,7 +1481,7 @@ retry:
1481 al->al_requested = data_blocks + ind_blocks; 1481 al->al_requested = data_blocks + ind_blocks;
1482 1482
1483 rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + 1483 rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA +
1484 RES_RG_HDR + ip->i_alloc->al_rgd->rd_length; 1484 RES_RG_HDR + gfs2_rg_blocks(al);
1485 if (gfs2_is_jdata(ip)) 1485 if (gfs2_is_jdata(ip))
1486 rblocks += data_blocks ? data_blocks : 1; 1486 rblocks += data_blocks ? data_blocks : 1;
1487 1487
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 9bc6dd9a544..58a9b9998b4 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -815,7 +815,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
815 goto out_alloc; 815 goto out_alloc;
816 816
817 if (nalloc) 817 if (nalloc)
818 blocks += al->al_rgd->rd_length + nalloc * ind_blocks + RES_STATFS; 818 blocks += gfs2_rg_blocks(al) + nalloc * ind_blocks + RES_STATFS;
819 819
820 error = gfs2_trans_begin(sdp, blocks, 0); 820 error = gfs2_trans_begin(sdp, blocks, 0);
821 if (error) 821 if (error)
@@ -1586,6 +1586,7 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
1586 error = gfs2_inplace_reserve(ip); 1586 error = gfs2_inplace_reserve(ip);
1587 if (error) 1587 if (error)
1588 goto out_alloc; 1588 goto out_alloc;
1589 blocks += gfs2_rg_blocks(al);
1589 } 1590 }
1590 1591
1591 error = gfs2_trans_begin(sdp, blocks + RES_DINODE + 1, 0); 1592 error = gfs2_trans_begin(sdp, blocks + RES_DINODE + 1, 0);
diff --git a/fs/gfs2/trans.h b/fs/gfs2/trans.h
index b849eb7ad37..fb56b783e02 100644
--- a/fs/gfs2/trans.h
+++ b/fs/gfs2/trans.h
@@ -26,6 +26,14 @@ struct gfs2_glock;
26#define RES_STATFS 1 26#define RES_STATFS 1
27#define RES_QUOTA 2 27#define RES_QUOTA 2
28 28
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 */
31static inline unsigned int gfs2_rg_blocks(const struct gfs2_alloc *al)
32{
33 return (al->al_requested < al->al_rgd->rd_length)?
34 al->al_requested + 1 : al->al_rgd->rd_length;
35}
36
29int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, 37int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
30 unsigned int revokes); 38 unsigned int revokes);
31 39
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 776af6eb4bc..30b58f07c8a 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -734,7 +734,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
734 goto out_gunlock_q; 734 goto out_gunlock_q;
735 735
736 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), 736 error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
737 blks + al->al_rgd->rd_length + 737 blks + gfs2_rg_blocks(al) +
738 RES_DINODE + RES_STATFS + RES_QUOTA, 0); 738 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
739 if (error) 739 if (error)
740 goto out_ipres; 740 goto out_ipres;