From fe6c991c52a0dd07d4a19d392fd65048226cb1bc Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 28 Jan 2008 11:13:02 -0600 Subject: [GFS2] Get rid of unneeded parameter in gfs2_rlist_alloc This patch removed the unnecessary parameter from function gfs2_rlist_alloc. The parameter was always passed in as 0. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index bee99704ea1..04febbc17a1 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -1347,7 +1347,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) else goto out; - gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE); for (x = 0; x < rlist.rl_rgrps; x++) { struct gfs2_rgrpd *rgd; -- cgit v1.2.3 From 5731be53e3d82aedd06e02574f833a57b07a08d2 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 1 Feb 2008 13:16:55 +0000 Subject: [GFS2] Update gfs2_trans_add_unrevoke to accept extents By adding an extra argument to gfs2_trans_add_unrevoke we can now specify an extent length of blocks to unrevoke. This means that we only need to make one pass through the list for each extent rather than each block. Currently the only extent length which is used is 1, but that will change in the future. Also gfs2_trans_add_unrevoke is removed from gfs2_alloc_meta since its the only difference between this and gfs2_alloc_data which is left. This will allow a future patch to merge these two functions into one (i.e. one call to allocate both data and metadata in a single extent in the future). Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 04febbc17a1..c7fa0a8b164 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -585,7 +585,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) u64 block; block = gfs2_alloc_meta(ip); - + gfs2_trans_add_unrevoke(sdp, block, 1); *bhp = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, *bhp, 1); gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA); @@ -644,7 +644,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, int mh_size = sizeof(struct gfs2_meta_header); block = gfs2_alloc_meta(ip); - + gfs2_trans_add_unrevoke(sdp, block, 1); bh = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, bh, 1); gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); @@ -968,7 +968,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, u64 blk; blk = gfs2_alloc_meta(ip); - + gfs2_trans_add_unrevoke(sdp, blk, 1); indbh = gfs2_meta_new(ip->i_gl, blk); gfs2_trans_add_bh(ip->i_gl, indbh, 1); gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); -- cgit v1.2.3 From 1639431a3f57b43da1e15e9268a1d691ac01ba26 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 1 Feb 2008 14:52:30 +0000 Subject: [GFS2] Merge gfs2_alloc_meta and gfs2_alloc_data Thanks to the preceeding patches, the only difference between these two functions is their name. We can thus merge them and call the new function gfs2_alloc_block to reflect the fact that it can allocate either kind of block. Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index c7fa0a8b164..f9f63bc21cd 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -584,7 +584,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) struct gfs2_ea_header *ea; u64 block; - block = gfs2_alloc_meta(ip); + block = gfs2_alloc_block(ip); gfs2_trans_add_unrevoke(sdp, block, 1); *bhp = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, *bhp, 1); @@ -643,7 +643,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, u64 block; int mh_size = sizeof(struct gfs2_meta_header); - block = gfs2_alloc_meta(ip); + block = gfs2_alloc_block(ip); gfs2_trans_add_unrevoke(sdp, block, 1); bh = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, bh, 1); @@ -967,7 +967,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, } else { u64 blk; - blk = gfs2_alloc_meta(ip); + blk = gfs2_alloc_block(ip); gfs2_trans_add_unrevoke(sdp, blk, 1); indbh = gfs2_meta_new(ip->i_gl, blk); gfs2_trans_add_bh(ip->i_gl, indbh, 1); -- cgit v1.2.3 From b45e41d7d56dfef1ae9e02e6c59990066ba82e5c Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Wed, 6 Feb 2008 10:11:15 +0000 Subject: [GFS2] Add extent allocation to block allocator Rather than having to allocate a single block at a time, this patch allows the block allocator to allocate an extent. Since there is no difference (so far as the block allocator is concerned) between data blocks and indirect blocks, it is posible to allocate a single extent and for the caller to unrevoke just the blocks required for indirect blocks. Currently the only bit of GFS2 to make use of this feature is the build height function. The intention is that gfs2_block_map will be changed to make use of this feature in future patches. Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index f9f63bc21cd..0e79cd54349 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -582,9 +582,10 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_ea_header *ea; + unsigned int n = 1; u64 block; - block = gfs2_alloc_block(ip); + block = gfs2_alloc_block(ip, &n); gfs2_trans_add_unrevoke(sdp, block, 1); *bhp = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, *bhp, 1); @@ -642,8 +643,9 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, struct buffer_head *bh; u64 block; int mh_size = sizeof(struct gfs2_meta_header); + unsigned int n = 1; - block = gfs2_alloc_block(ip); + block = gfs2_alloc_block(ip, &n); gfs2_trans_add_unrevoke(sdp, block, 1); bh = gfs2_meta_new(ip->i_gl, block); gfs2_trans_add_bh(ip->i_gl, bh, 1); @@ -966,8 +968,8 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, gfs2_trans_add_bh(ip->i_gl, indbh, 1); } else { u64 blk; - - blk = gfs2_alloc_block(ip); + unsigned int n = 1; + blk = gfs2_alloc_block(ip, &n); gfs2_trans_add_unrevoke(sdp, blk, 1); indbh = gfs2_meta_new(ip->i_gl, blk); gfs2_trans_add_bh(ip->i_gl, indbh, 1); -- cgit v1.2.3 From 77658aad226866fb94097236d14d41a88aaab2ec Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Tue, 12 Feb 2008 14:17:27 +0000 Subject: [GFS2] Eliminate (almost) duplicate field from gfs2_inode The blocks counter is almost a duplicate of the i_blocks field in the VFS inode. The only difference is that i_blocks can be only 32bits long for 32bit arch without large single file support. Since GFS2 doesn't handle the non-large single file case (for 32 bit anyway) this adds a new config dependency on 64BIT || LSF. This has always been the case, however we've never explicitly said so before. Even if we do add support for the non-LSF case, we will still not require this field to be duplicated since we will not be able to access oversized files anyway. So the net result of all this is that we shave 8 bytes from a gfs2_inode and get our config deps correct. Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 0e79cd54349..76ead1acfcc 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -277,10 +277,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, } *dataptrs = 0; - if (!ip->i_di.di_blocks) - gfs2_consist_inode(ip); - ip->i_di.di_blocks--; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, -1); } if (bstart) gfs2_free_meta(ip, bstart, blen); @@ -598,8 +595,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) ea->ea_flags = GFS2_EAFLAG_LAST; ea->ea_num_ptrs = 0; - ip->i_di.di_blocks++; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, 1); return 0; } @@ -651,8 +647,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, gfs2_trans_add_bh(ip->i_gl, bh, 1); gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); - ip->i_di.di_blocks++; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, 1); copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : data_len; @@ -980,8 +975,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, *eablk = cpu_to_be64(ip->i_di.di_eattr); ip->i_di.di_eattr = blk; ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; - ip->i_di.di_blocks++; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, 1); eablk++; } @@ -1389,10 +1383,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) } *eablk = 0; - if (!ip->i_di.di_blocks) - gfs2_consist_inode(ip); - ip->i_di.di_blocks--; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, -1); } if (bstart) gfs2_free_meta(ip, bstart, blen); @@ -1444,10 +1435,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip) gfs2_free_meta(ip, ip->i_di.di_eattr, 1); ip->i_di.di_eattr = 0; - if (!ip->i_di.di_blocks) - gfs2_consist_inode(ip); - ip->i_di.di_blocks--; - gfs2_set_inode_blocks(&ip->i_inode); + gfs2_add_inode_blocks(&ip->i_inode, -1); error = gfs2_meta_inode_buffer(ip, &dibh); if (!error) { -- cgit v1.2.3 From 182fe5abd8ebbb3a00c1be91f44e4783e139918c Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Mon, 3 Mar 2008 21:54:21 +0300 Subject: [GFS2] possible null pointer dereference fixup gfs2_alloc_get may fail so we have to check it to prevent NULL pointer dereference. Signed-off-by: Cyrill Gorcunov Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 76ead1acfcc..288d5e6ad93 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -318,6 +318,8 @@ static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, int error; al = gfs2_alloc_get(ip); + if (!al) + return -ENOMEM; error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) @@ -681,6 +683,8 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, int error; al = gfs2_alloc_get(ip); + if (!al) + return -ENOMEM; error = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) @@ -1464,6 +1468,8 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip) int error; al = gfs2_alloc_get(ip); + if (!al) + return -ENOMEM; error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); if (error) -- cgit v1.2.3 From d82661d96993ac4efc1d54259ea85ffcd9b8bec6 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 10 Mar 2008 15:34:50 +0000 Subject: [GFS2] Streamline quota lock/check for no-quota case This patch streamlines the quota checking in the "no quota" case by making the check inline in the calling function, thus reducing the number of function calls. Eventually we might be able to remove the checks from the gfs2_quota_lock() and gfs2_quota_check() functions, but currently we can't as there are a very few places in the code which need to call these functions directly still. Signed-off-by: Steven Whitehouse Cc: Abhijith Das --- fs/gfs2/eattr.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 288d5e6ad93..81755925a75 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -686,14 +686,10 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, if (!al) return -ENOMEM; - error = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + error = gfs2_quota_lock_check(ip); if (error) goto out; - error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); - if (error) - goto out_gunlock_q; - al->al_requested = blks; error = gfs2_inplace_reserve(ip); -- cgit v1.2.3 From 16c5f06f15ad4e5a5d6e90b78ffb1ac14319e445 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 9 Apr 2008 09:33:41 -0400 Subject: [GFS2] fix GFP_KERNEL misuses There are several places where GFP_KERNEL allocations happen under a glock, which will result in hangs if we're under memory pressure and go to re-enter the fs in order to flush stuff out. This patch changes the culprits to GFS_NOFS to keep this problem from happening. Thank you, Signed-off-by: Josef Bacik Signed-off-by: Steven Whitehouse --- fs/gfs2/eattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/gfs2/eattr.c') diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 81755925a75..e3f76f451b0 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c @@ -448,7 +448,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, unsigned int x; int error = 0; - bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL); + bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); if (!bh) return -ENOMEM; @@ -1206,7 +1206,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, unsigned int x; int error; - bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_KERNEL); + bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); if (!bh) return -ENOMEM; -- cgit v1.2.3