From a13b8c5f2381495879e6facd3b3ada51c9e68194 Mon Sep 17 00:00:00 2001 From: Wendy Cheng Date: Mon, 20 Aug 2007 09:29:53 -0400 Subject: [GFS2] Reduce truncate IO traffic Current GFS2 setattr call unconditionally invokes do_shrink even the requested size and actual file size are equal. This has generated large amount of extra IOs found during NFS benchmark runs. This patch moves the relevant logic out of shrink code path. Since setattr is a system call, the time stamps update is still required. Signed-off-by: S. Wendy Cheng Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'fs/gfs2/bmap.c') diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index cd805a6..9b89904 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -1085,6 +1085,33 @@ static int do_shrink(struct gfs2_inode *ip, u64 size) return error; } +static int do_touch(struct gfs2_inode *ip, u64 size) +{ + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + struct buffer_head *dibh; + int error; + + error = gfs2_trans_begin(sdp, RES_DINODE, 0); + if (error) + return error; + + down_write(&ip->i_rw_mutex); + + error = gfs2_meta_inode_buffer(ip, &dibh); + if (error) + goto do_touch_out; + + ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; + gfs2_trans_add_bh(ip->i_gl, dibh, 1); + gfs2_dinode_out(ip, dibh->b_data); + brelse(dibh); + +do_touch_out: + up_write(&ip->i_rw_mutex); + gfs2_trans_end(sdp); + return error; +} + /** * gfs2_truncatei - make a file a given size * @ip: the inode @@ -1105,8 +1132,11 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) if (size > ip->i_di.di_size) error = do_grow(ip, size); - else + else if (size < ip->i_di.di_size) error = do_shrink(ip, size); + else + /* update time stamps */ + error = do_touch(ip, size); return error; } -- cgit v1.1 From eaf965270ffff3086ef929e660ace45e862cfd2d Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 27 Aug 2007 09:49:37 +0100 Subject: [GFS2] Don't mark jdata dirty in gfs2_unstuffer_page() Journaled data is marked dirty by gfs2_unpin and should not be marked dirty here. Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs/gfs2/bmap.c') diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 9b89904..1e56f4d 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -95,7 +95,8 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, set_buffer_uptodate(bh); if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) gfs2_trans_add_bh(ip->i_gl, bh, 0); - mark_buffer_dirty(bh); + if (!gfs2_is_jdata(ip)) + mark_buffer_dirty(bh); if (release) { unlock_page(page); -- cgit v1.1 From 8475487befb29eeb038fef374a7433d276336a25 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Sun, 2 Sep 2007 10:55:29 +0100 Subject: [GFS2] Fix ordering of dirty/journal for ordered buffer unstuffing Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/bmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/gfs2/bmap.c') diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 1e56f4d..93fa427 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -93,10 +93,10 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, map_bh(bh, inode->i_sb, block); set_buffer_uptodate(bh); - if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) - gfs2_trans_add_bh(ip->i_gl, bh, 0); if (!gfs2_is_jdata(ip)) mark_buffer_dirty(bh); + if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) + gfs2_trans_add_bh(ip->i_gl, bh, 0); if (release) { unlock_page(page); -- cgit v1.1