diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-11-23 10:51:34 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-11-30 10:36:42 -0500 |
commit | b004157ab5b374a498a5874cda68c389219d23e7 (patch) | |
tree | 1e7d7d5c62f3e12cc453e763bbff139b47458be4 /fs/gfs2/ops_super.c | |
parent | ae619320b22f8e0b2bbe4a3a5ac2f9ccf08d7ec2 (diff) |
[GFS2] Fix journal flush problem
This fixes a bug which resulted in poor performance due to flushing
the journal too often. The code path in question was via the inode_go_sync()
function in glops.c. The solution is not to flush the journal immediately
when inodes are ejected from memory, but batch up the work for glockd to
deal with later on. This means that glocks may now live on beyond the end of
the lifetime of their inodes (but not very much longer in the normal case).
Also fixed in this patch is a bug (which was hidden by the bug mentioned above) in
calculation of the number of free journal blocks.
The gfs2_logd process has been altered to be more responsive to the journal
filling up. We now wake it up when the number of uncommitted journal blocks
has reached the threshold level rather than trying to flush directly at the
end of each transaction. This again means doing fewer, but larger, log
flushes in general.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_super.c')
-rw-r--r-- | fs/gfs2/ops_super.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 863517569223..7685b46f934b 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -157,7 +157,8 @@ static void gfs2_write_super(struct super_block *sb) | |||
157 | static int gfs2_sync_fs(struct super_block *sb, int wait) | 157 | static int gfs2_sync_fs(struct super_block *sb, int wait) |
158 | { | 158 | { |
159 | sb->s_dirt = 0; | 159 | sb->s_dirt = 0; |
160 | gfs2_log_flush(sb->s_fs_info, NULL); | 160 | if (wait) |
161 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
161 | return 0; | 162 | return 0; |
162 | } | 163 | } |
163 | 164 | ||
@@ -293,8 +294,6 @@ static void gfs2_clear_inode(struct inode *inode) | |||
293 | */ | 294 | */ |
294 | if (inode->i_private) { | 295 | if (inode->i_private) { |
295 | struct gfs2_inode *ip = GFS2_I(inode); | 296 | struct gfs2_inode *ip = GFS2_I(inode); |
296 | gfs2_glock_inode_squish(inode); | ||
297 | gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED); | ||
298 | ip->i_gl->gl_object = NULL; | 297 | ip->i_gl->gl_object = NULL; |
299 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | 298 | gfs2_glock_schedule_for_reclaim(ip->i_gl); |
300 | gfs2_glock_put(ip->i_gl); | 299 | gfs2_glock_put(ip->i_gl); |
@@ -395,7 +394,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
395 | if (!inode->i_private) | 394 | if (!inode->i_private) |
396 | goto out; | 395 | goto out; |
397 | 396 | ||
398 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh); | 397 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); |
399 | if (unlikely(error)) { | 398 | if (unlikely(error)) { |
400 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 399 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
401 | goto out; | 400 | goto out; |