diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2010-07-05 15:15:00 +0300 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-09 16:48:51 -0400 |
commit | 7435d50611b04c1155a939a9f373154a53606592 (patch) | |
tree | 5800b04dbaf99dfc6958bb777c39d98e7de94593 /fs/affs | |
parent | 669d5f1f608f7de29bb467bb239517a414e43777 (diff) | |
download | lwn-7435d50611b04c1155a939a9f373154a53606592.tar.gz lwn-7435d50611b04c1155a939a9f373154a53606592.zip |
AFFS: wait for sb synchronization when needed
AFFS does not ever wait for superblock synchronization in
->put_super(), ->write_super, and ->sync_fs().
However, it should wait for synchronization in ->put_super() because
it is about to be unmounted, in ->write_super() because this is
periodic SB synchronization performed from a separate kernel thread,
and in ->sync_fs() it should respect the 'wait' flag. This patch fixes
the situation.
Also, in ->put_super(), do not write the SB if it is not dirty.
Tested-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/affs')
-rw-r--r-- | fs/affs/super.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c index fde3b9ae700f..33c4e7eef470 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -26,7 +26,7 @@ static int affs_statfs(struct dentry *dentry, struct kstatfs *buf); static int affs_remount (struct super_block *sb, int *flags, char *data); static void -affs_commit_super(struct super_block *sb, int clean) +affs_commit_super(struct super_block *sb, int wait, int clean) { struct affs_sb_info *sbi = AFFS_SB(sb); struct buffer_head *bh = sbi->s_root_bh; @@ -36,6 +36,8 @@ affs_commit_super(struct super_block *sb, int clean) secs_to_datestamp(get_seconds(), &tail->disk_change); affs_fix_checksum(sb, bh); mark_buffer_dirty(bh); + if (wait) + sync_dirty_buffer(bh); } static void @@ -46,8 +48,8 @@ affs_put_super(struct super_block *sb) lock_kernel(); - if (!(sb->s_flags & MS_RDONLY)) - affs_commit_super(sb, 1); + if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt) + affs_commit_super(sb, 1, 1); kfree(sbi->s_prefix); affs_free_bitmap(sb); @@ -63,7 +65,7 @@ affs_write_super(struct super_block *sb) { lock_super(sb); if (!(sb->s_flags & MS_RDONLY)) - affs_commit_super(sb, 2); + affs_commit_super(sb, 1, 2); sb->s_dirt = 0; unlock_super(sb); @@ -74,7 +76,7 @@ static int affs_sync_fs(struct super_block *sb, int wait) { lock_super(sb); - affs_commit_super(sb, 2); + affs_commit_super(sb, wait, 2); sb->s_dirt = 0; unlock_super(sb); return 0; |