aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-06-11 23:14:04 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-06-11 23:14:04 -0400
commita0375156ca1041574b5d47cc7e32f10b891151b0 (patch)
treeb791961012b9348f289c3dda5dc071bdf9b736d2 /fs
parent7e27d6e778cd87b6f2415515d7127eba53fe5d02 (diff)
ext4: Clean up s_dirt handling
We don't need to set s_dirt in most of the ext4 code when journaling is enabled. In ext3/4 some of the summary statistics for # of free inodes, blocks, and directories are calculated from the per-block group statistics when the file system is mounted or unmounted. As a result the superblock doesn't have to be updated, either via the journal or by setting s_dirt. There are a few exceptions, most notably when resizing the file system, where the superblock needs to be modified --- and in that case it should be done as a journalled operation if possible, and s_dirt set only in no-journal mode. This patch will optimize out some unneeded disk writes when using ext4 with a journal. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/balloc.c6
-rw-r--r--fs/ext4/ext4.h6
-rw-r--r--fs/ext4/ext4_jbd2.c16
-rw-r--r--fs/ext4/ext4_jbd2.h5
-rw-r--r--fs/ext4/file.c2
-rw-r--r--fs/ext4/ialloc.c4
-rw-r--r--fs/ext4/mballoc.c4
-rw-r--r--fs/ext4/resize.c6
-rw-r--r--fs/ext4/xattr.c3
9 files changed, 36 insertions, 16 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 95b7594c76f9..bd30799a43ed 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -377,14 +377,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
377 ext4_grpblk_t bit; 377 ext4_grpblk_t bit;
378 unsigned int i; 378 unsigned int i;
379 struct ext4_group_desc *desc; 379 struct ext4_group_desc *desc;
380 struct ext4_super_block *es; 380 struct ext4_sb_info *sbi = EXT4_SB(sb);
381 struct ext4_sb_info *sbi;
382 int err = 0, ret, blk_free_count; 381 int err = 0, ret, blk_free_count;
383 ext4_grpblk_t blocks_freed; 382 ext4_grpblk_t blocks_freed;
384 struct ext4_group_info *grp; 383 struct ext4_group_info *grp;
385 384
386 sbi = EXT4_SB(sb);
387 es = sbi->s_es;
388 ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); 385 ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);
389 386
390 ext4_get_group_no_and_offset(sb, block, &block_group, &bit); 387 ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
@@ -477,7 +474,6 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
477 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh); 474 ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
478 if (!err) 475 if (!err)
479 err = ret; 476 err = ret;
480 sb->s_dirt = 1;
481 477
482error_return: 478error_return:
483 brelse(bitmap_bh); 479 brelse(bitmap_bh);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 19a4de57128a..8b56b53328eb 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1860,6 +1860,12 @@ static inline void ext4_unlock_group(struct super_block *sb,
1860 spin_unlock(ext4_group_lock_ptr(sb, group)); 1860 spin_unlock(ext4_group_lock_ptr(sb, group));
1861} 1861}
1862 1862
1863static inline void ext4_mark_super_dirty(struct super_block *sb)
1864{
1865 if (EXT4_SB(sb)->s_journal == NULL)
1866 sb->s_dirt =1;
1867}
1868
1863/* 1869/*
1864 * Inodes and files operations 1870 * Inodes and files operations
1865 */ 1871 */
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index 53d2764d71ca..cfd27b38fa15 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -143,3 +143,19 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
143 } 143 }
144 return err; 144 return err;
145} 145}
146
147int __ext4_handle_dirty_super(const char *where, handle_t *handle,
148 struct super_block *sb)
149{
150 struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
151 int err = 0;
152
153 if (ext4_handle_valid(handle)) {
154 err = jbd2_journal_dirty_metadata(handle, bh);
155 if (err)
156 ext4_journal_abort_handle(where, __func__, bh,
157 handle, err);
158 } else
159 sb->s_dirt = 1;
160 return err;
161}
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index dade0c024797..8ae8168900bf 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -141,6 +141,9 @@ int __ext4_journal_get_create_access(const char *where,
141int __ext4_handle_dirty_metadata(const char *where, handle_t *handle, 141int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
142 struct inode *inode, struct buffer_head *bh); 142 struct inode *inode, struct buffer_head *bh);
143 143
144int __ext4_handle_dirty_super(const char *where, handle_t *handle,
145 struct super_block *sb);
146
144#define ext4_journal_get_undo_access(handle, bh) \ 147#define ext4_journal_get_undo_access(handle, bh) \
145 __ext4_journal_get_undo_access(__func__, (handle), (bh)) 148 __ext4_journal_get_undo_access(__func__, (handle), (bh))
146#define ext4_journal_get_write_access(handle, bh) \ 149#define ext4_journal_get_write_access(handle, bh) \
@@ -152,6 +155,8 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
152 __ext4_journal_get_create_access(__func__, (handle), (bh)) 155 __ext4_journal_get_create_access(__func__, (handle), (bh))
153#define ext4_handle_dirty_metadata(handle, inode, bh) \ 156#define ext4_handle_dirty_metadata(handle, inode, bh) \
154 __ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh)) 157 __ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
158#define ext4_handle_dirty_super(handle, sb) \
159 __ext4_handle_dirty_super(__func__, (handle), (sb))
155 160
156handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); 161handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
157int __ext4_journal_stop(const char *where, handle_t *handle); 162int __ext4_journal_stop(const char *where, handle_t *handle);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 5313ae4cda2d..bd411c12d63d 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -123,7 +123,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
123 if (!IS_ERR(cp)) { 123 if (!IS_ERR(cp)) {
124 memcpy(sbi->s_es->s_last_mounted, cp, 124 memcpy(sbi->s_es->s_last_mounted, cp,
125 sizeof(sbi->s_es->s_last_mounted)); 125 sizeof(sbi->s_es->s_last_mounted));
126 sb->s_dirt = 1; 126 ext4_mark_super_dirty(sb);
127 } 127 }
128 } 128 }
129 return dquot_file_open(inode, filp); 129 return dquot_file_open(inode, filp);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 25c4b3173fd9..ac377505ed57 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -279,7 +279,7 @@ out:
279 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); 279 err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
280 if (!fatal) 280 if (!fatal)
281 fatal = err; 281 fatal = err;
282 sb->s_dirt = 1; 282 ext4_mark_super_dirty(sb);
283 } else 283 } else
284 ext4_error(sb, "bit already cleared for inode %lu", ino); 284 ext4_error(sb, "bit already cleared for inode %lu", ino);
285 285
@@ -965,7 +965,7 @@ got:
965 percpu_counter_dec(&sbi->s_freeinodes_counter); 965 percpu_counter_dec(&sbi->s_freeinodes_counter);
966 if (S_ISDIR(mode)) 966 if (S_ISDIR(mode))
967 percpu_counter_inc(&sbi->s_dirs_counter); 967 percpu_counter_inc(&sbi->s_dirs_counter);
968 sb->s_dirt = 1; 968 ext4_mark_super_dirty(sb);
969 969
970 if (sbi->s_log_groups_per_flex) { 970 if (sbi->s_log_groups_per_flex) {
971 flex_group = ext4_flex_group(sbi, group); 971 flex_group = ext4_flex_group(sbi, group);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 12b3bc026a68..d9d267181ddc 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2812,7 +2812,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
2812 err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh); 2812 err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
2813 2813
2814out_err: 2814out_err:
2815 sb->s_dirt = 1; 2815 ext4_mark_super_dirty(sb);
2816 brelse(bitmap_bh); 2816 brelse(bitmap_bh);
2817 return err; 2817 return err;
2818} 2818}
@@ -4680,7 +4680,7 @@ do_more:
4680 put_bh(bitmap_bh); 4680 put_bh(bitmap_bh);
4681 goto do_more; 4681 goto do_more;
4682 } 4682 }
4683 sb->s_dirt = 1; 4683 ext4_mark_super_dirty(sb);
4684error_return: 4684error_return:
4685 if (freed) 4685 if (freed)
4686 dquot_free_block(inode, freed); 4686 dquot_free_block(inode, freed);
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 6df797eb9aeb..27527ae466ea 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -921,8 +921,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
921 &sbi->s_flex_groups[flex_group].free_inodes); 921 &sbi->s_flex_groups[flex_group].free_inodes);
922 } 922 }
923 923
924 ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh); 924 ext4_handle_dirty_super(handle, sb);
925 sb->s_dirt = 1;
926 925
927exit_journal: 926exit_journal:
928 mutex_unlock(&sbi->s_resize_lock); 927 mutex_unlock(&sbi->s_resize_lock);
@@ -1045,13 +1044,12 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
1045 goto exit_put; 1044 goto exit_put;
1046 } 1045 }
1047 ext4_blocks_count_set(es, o_blocks_count + add); 1046 ext4_blocks_count_set(es, o_blocks_count + add);
1048 ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
1049 sb->s_dirt = 1;
1050 mutex_unlock(&EXT4_SB(sb)->s_resize_lock); 1047 mutex_unlock(&EXT4_SB(sb)->s_resize_lock);
1051 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, 1048 ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
1052 o_blocks_count + add); 1049 o_blocks_count + add);
1053 /* We add the blocks to the bitmap and set the group need init bit */ 1050 /* We add the blocks to the bitmap and set the group need init bit */
1054 ext4_add_groupblocks(handle, sb, o_blocks_count, add); 1051 ext4_add_groupblocks(handle, sb, o_blocks_count, add);
1052 ext4_handle_dirty_super(handle, sb);
1055 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, 1053 ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
1056 o_blocks_count + add); 1054 o_blocks_count + add);
1057 if ((err = ext4_journal_stop(handle))) 1055 if ((err = ext4_journal_stop(handle)))
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 04338009793a..a6f314249574 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -458,8 +458,7 @@ static void ext4_xattr_update_super_block(handle_t *handle,
458 458
459 if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { 459 if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
460 EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR); 460 EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
461 sb->s_dirt = 1; 461 ext4_handle_dirty_super(handle, sb);
462 ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
463 } 462 }
464} 463}
465 464