aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWendy Cheng <wcheng@redhat.com>2007-08-20 09:29:53 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:55:36 -0400
commita13b8c5f2381495879e6facd3b3ada51c9e68194 (patch)
tree79852951c3074af8b2d9e84fdc03d622bc022be3
parent9a5ad13856cbd10be429f09517c51277c02530f7 (diff)
[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 <wcheng@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/bmap.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index cd805a66880d..9b8990444e6c 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)
1085 return error; 1085 return error;
1086} 1086}
1087 1087
1088static int do_touch(struct gfs2_inode *ip, u64 size)
1089{
1090 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1091 struct buffer_head *dibh;
1092 int error;
1093
1094 error = gfs2_trans_begin(sdp, RES_DINODE, 0);
1095 if (error)
1096 return error;
1097
1098 down_write(&ip->i_rw_mutex);
1099
1100 error = gfs2_meta_inode_buffer(ip, &dibh);
1101 if (error)
1102 goto do_touch_out;
1103
1104 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1105 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1106 gfs2_dinode_out(ip, dibh->b_data);
1107 brelse(dibh);
1108
1109do_touch_out:
1110 up_write(&ip->i_rw_mutex);
1111 gfs2_trans_end(sdp);
1112 return error;
1113}
1114
1088/** 1115/**
1089 * gfs2_truncatei - make a file a given size 1116 * gfs2_truncatei - make a file a given size
1090 * @ip: the inode 1117 * @ip: the inode
@@ -1105,8 +1132,11 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
1105 1132
1106 if (size > ip->i_di.di_size) 1133 if (size > ip->i_di.di_size)
1107 error = do_grow(ip, size); 1134 error = do_grow(ip, size);
1108 else 1135 else if (size < ip->i_di.di_size)
1109 error = do_shrink(ip, size); 1136 error = do_shrink(ip, size);
1137 else
1138 /* update time stamps */
1139 error = do_touch(ip, size);
1110 1140
1111 return error; 1141 return error;
1112} 1142}