aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-07-05 08:15:00 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-09 16:48:51 -0400
commit7435d50611b04c1155a939a9f373154a53606592 (patch)
tree5800b04dbaf99dfc6958bb777c39d98e7de94593
parent669d5f1f608f7de29bb467bb239517a414e43777 (diff)
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>
-rw-r--r--fs/affs/super.c12
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);
26static int affs_remount (struct super_block *sb, int *flags, char *data); 26static int affs_remount (struct super_block *sb, int *flags, char *data);
27 27
28static void 28static void
29affs_commit_super(struct super_block *sb, int clean) 29affs_commit_super(struct super_block *sb, int wait, int clean)
30{ 30{
31 struct affs_sb_info *sbi = AFFS_SB(sb); 31 struct affs_sb_info *sbi = AFFS_SB(sb);
32 struct buffer_head *bh = sbi->s_root_bh; 32 struct buffer_head *bh = sbi->s_root_bh;
@@ -36,6 +36,8 @@ affs_commit_super(struct super_block *sb, int clean)
36 secs_to_datestamp(get_seconds(), &tail->disk_change); 36 secs_to_datestamp(get_seconds(), &tail->disk_change);
37 affs_fix_checksum(sb, bh); 37 affs_fix_checksum(sb, bh);
38 mark_buffer_dirty(bh); 38 mark_buffer_dirty(bh);
39 if (wait)
40 sync_dirty_buffer(bh);
39} 41}
40 42
41static void 43static void
@@ -46,8 +48,8 @@ affs_put_super(struct super_block *sb)
46 48
47 lock_kernel(); 49 lock_kernel();
48 50
49 if (!(sb->s_flags & MS_RDONLY)) 51 if (!(sb->s_flags & MS_RDONLY) && sb->s_dirt)
50 affs_commit_super(sb, 1); 52 affs_commit_super(sb, 1, 1);
51 53
52 kfree(sbi->s_prefix); 54 kfree(sbi->s_prefix);
53 affs_free_bitmap(sb); 55 affs_free_bitmap(sb);
@@ -63,7 +65,7 @@ affs_write_super(struct super_block *sb)
63{ 65{
64 lock_super(sb); 66 lock_super(sb);
65 if (!(sb->s_flags & MS_RDONLY)) 67 if (!(sb->s_flags & MS_RDONLY))
66 affs_commit_super(sb, 2); 68 affs_commit_super(sb, 1, 2);
67 sb->s_dirt = 0; 69 sb->s_dirt = 0;
68 unlock_super(sb); 70 unlock_super(sb);
69 71
@@ -74,7 +76,7 @@ static int
74affs_sync_fs(struct super_block *sb, int wait) 76affs_sync_fs(struct super_block *sb, int wait)
75{ 77{
76 lock_super(sb); 78 lock_super(sb);
77 affs_commit_super(sb, 2); 79 affs_commit_super(sb, wait, 2);
78 sb->s_dirt = 0; 80 sb->s_dirt = 0;
79 unlock_super(sb); 81 unlock_super(sb);
80 return 0; 82 return 0;