[PATCHv5 11/16] ext2: fix race condition in marking SB dirty

From: Artem Bityutskiy
Date: Sun Jun 06 2010 - 10:54:27 EST


From: Artem Bityutskiy <Artem.Bityutskiy@xxxxxxxxx>

When synchronizing the superblock, ext2 first initiates the SB write
(a) and then marks the superblock as clean (b). However, meanwhile
(between (a) and (b)) someone else can modify the superblock and
mark it as dirty. This would be a race condition, and the result
would be that we'd end up with a modified superblock which would
nevertheless be marked as clean (because of (b)). This means that
'sync_supers()' would never call our '->write_super()', at least
not until yet another SB change happens.

This patch fixes this race condition by marking the superblock as
clean before initiating the write operation.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@xxxxxxxxx>
Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---
fs/ext2/super.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 39eb5df..611d4c4 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1145,6 +1145,7 @@ static void ext2_clear_super_error(struct super_block *sb)
static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es,
int wait)
{
+ sb_mark_clean(sb);
ext2_clear_super_error(sb);
spin_lock(&EXT2_SB(sb)->s_lock);
es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb));
@@ -1155,7 +1156,6 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es,
mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
if (wait)
sync_dirty_buffer(EXT2_SB(sb)->s_sbh);
- sb_mark_clean(sb);
}

/*
--
1.7.0.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/