diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-04-30 21:24:04 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-04-30 21:24:04 -0400 |
commit | 7234ab2a55e77784b44cf2d862136d9e41b8d98a (patch) | |
tree | cad3f1ee096243529125b3d6a028cc1426773b9c /fs/ext4/super.c | |
parent | e2d670523c6c4ccb0fca9f3ab1b8f066d9aa57d6 (diff) |
ext4: Fix and simplify s_dirt handling
The s_dirt flag wasn't completely handled correctly, but it didn't
really matter when journalling was enabled. It turns out that when
ext4 runs without a journal, we don't clear s_dirt in places where we
should have, with the result that the high-level write_super()
function was writing the superblock when it wasn't necessary.
So we fix this by making ext4_commit_super() clear the s_dirt flag,
and removing many of the other places where s_dirt is manipulated.
When journalling is enabled, the s_dirt flag might be left set more
often, but s_dirt really doesn't matter when journalling is enabled.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 14 |
1 files changed, 3 insertions, 11 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index ad4c9be4abdc..7c7a08af1200 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3128,7 +3128,6 @@ static int ext4_load_journal(struct super_block *sb, | |||
3128 | if (journal_devnum && | 3128 | if (journal_devnum && |
3129 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { | 3129 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { |
3130 | es->s_journal_dev = cpu_to_le32(journal_devnum); | 3130 | es->s_journal_dev = cpu_to_le32(journal_devnum); |
3131 | sb->s_dirt = 1; | ||
3132 | 3131 | ||
3133 | /* Make sure we flush the recovery flag to disk. */ | 3132 | /* Make sure we flush the recovery flag to disk. */ |
3134 | ext4_commit_super(sb, 1); | 3133 | ext4_commit_super(sb, 1); |
@@ -3168,7 +3167,7 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3168 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3167 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3169 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( | 3168 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( |
3170 | &EXT4_SB(sb)->s_freeinodes_counter)); | 3169 | &EXT4_SB(sb)->s_freeinodes_counter)); |
3171 | 3170 | sb->s_dirt = 0; | |
3172 | BUFFER_TRACE(sbh, "marking dirty"); | 3171 | BUFFER_TRACE(sbh, "marking dirty"); |
3173 | mark_buffer_dirty(sbh); | 3172 | mark_buffer_dirty(sbh); |
3174 | if (sync) { | 3173 | if (sync) { |
@@ -3210,7 +3209,6 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
3210 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 3209 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
3211 | sb->s_flags & MS_RDONLY) { | 3210 | sb->s_flags & MS_RDONLY) { |
3212 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3211 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
3213 | sb->s_dirt = 0; | ||
3214 | ext4_commit_super(sb, 1); | 3212 | ext4_commit_super(sb, 1); |
3215 | } | 3213 | } |
3216 | unlock_super(sb); | 3214 | unlock_super(sb); |
@@ -3271,10 +3269,8 @@ int ext4_force_commit(struct super_block *sb) | |||
3271 | return 0; | 3269 | return 0; |
3272 | 3270 | ||
3273 | journal = EXT4_SB(sb)->s_journal; | 3271 | journal = EXT4_SB(sb)->s_journal; |
3274 | if (journal) { | 3272 | if (journal) |
3275 | sb->s_dirt = 0; | ||
3276 | ret = ext4_journal_force_commit(journal); | 3273 | ret = ext4_journal_force_commit(journal); |
3277 | } | ||
3278 | 3274 | ||
3279 | return ret; | 3275 | return ret; |
3280 | } | 3276 | } |
@@ -3282,15 +3278,13 @@ int ext4_force_commit(struct super_block *sb) | |||
3282 | /* | 3278 | /* |
3283 | * Ext4 always journals updates to the superblock itself, so we don't | 3279 | * Ext4 always journals updates to the superblock itself, so we don't |
3284 | * have to propagate any other updates to the superblock on disk at this | 3280 | * have to propagate any other updates to the superblock on disk at this |
3285 | * point. (We can probably nuke this function altogether, and remove | 3281 | * point if the journalling is enabled. |
3286 | * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...) | ||
3287 | */ | 3282 | */ |
3288 | static void ext4_write_super(struct super_block *sb) | 3283 | static void ext4_write_super(struct super_block *sb) |
3289 | { | 3284 | { |
3290 | if (EXT4_SB(sb)->s_journal) { | 3285 | if (EXT4_SB(sb)->s_journal) { |
3291 | if (mutex_trylock(&sb->s_lock) != 0) | 3286 | if (mutex_trylock(&sb->s_lock) != 0) |
3292 | BUG(); | 3287 | BUG(); |
3293 | sb->s_dirt = 0; | ||
3294 | } else { | 3288 | } else { |
3295 | ext4_commit_super(sb, 1); | 3289 | ext4_commit_super(sb, 1); |
3296 | } | 3290 | } |
@@ -3302,7 +3296,6 @@ static int ext4_sync_fs(struct super_block *sb, int wait) | |||
3302 | tid_t target; | 3296 | tid_t target; |
3303 | 3297 | ||
3304 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); | 3298 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); |
3305 | sb->s_dirt = 0; | ||
3306 | if (EXT4_SB(sb)->s_journal) { | 3299 | if (EXT4_SB(sb)->s_journal) { |
3307 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, | 3300 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, |
3308 | &target)) { | 3301 | &target)) { |
@@ -3324,7 +3317,6 @@ static int ext4_freeze(struct super_block *sb) | |||
3324 | { | 3317 | { |
3325 | int error = 0; | 3318 | int error = 0; |
3326 | journal_t *journal; | 3319 | journal_t *journal; |
3327 | sb->s_dirt = 0; | ||
3328 | 3320 | ||
3329 | if (!(sb->s_flags & MS_RDONLY)) { | 3321 | if (!(sb->s_flags & MS_RDONLY)) { |
3330 | journal = EXT4_SB(sb)->s_journal; | 3322 | journal = EXT4_SB(sb)->s_journal; |