Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0375156 authored by Theodore Ts'o's avatar Theodore Ts'o
Browse files

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: default avatar"Theodore Ts'o" <tytso@mit.edu>
parent 7e27d6e7
Loading
Loading
Loading
Loading
+1 −5
Original line number Original line Diff line number Diff line
@@ -377,14 +377,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
	ext4_grpblk_t bit;
	ext4_grpblk_t bit;
	unsigned int i;
	unsigned int i;
	struct ext4_group_desc *desc;
	struct ext4_group_desc *desc;
	struct ext4_super_block *es;
	struct ext4_sb_info *sbi = EXT4_SB(sb);
	struct ext4_sb_info *sbi;
	int err = 0, ret, blk_free_count;
	int err = 0, ret, blk_free_count;
	ext4_grpblk_t blocks_freed;
	ext4_grpblk_t blocks_freed;
	struct ext4_group_info *grp;
	struct ext4_group_info *grp;


	sbi = EXT4_SB(sb);
	es = sbi->s_es;
	ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);
	ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1);


	ext4_get_group_no_and_offset(sb, block, &block_group, &bit);
	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,
	ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
	ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
	if (!err)
	if (!err)
		err = ret;
		err = ret;
	sb->s_dirt = 1;


error_return:
error_return:
	brelse(bitmap_bh);
	brelse(bitmap_bh);
+6 −0
Original line number Original line Diff line number Diff line
@@ -1860,6 +1860,12 @@ static inline void ext4_unlock_group(struct super_block *sb,
	spin_unlock(ext4_group_lock_ptr(sb, group));
	spin_unlock(ext4_group_lock_ptr(sb, group));
}
}


static inline void ext4_mark_super_dirty(struct super_block *sb)
{
	if (EXT4_SB(sb)->s_journal == NULL)
		sb->s_dirt =1;
}

/*
/*
 * Inodes and files operations
 * Inodes and files operations
 */
 */
+16 −0
Original line number Original line Diff line number Diff line
@@ -143,3 +143,19 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
	}
	}
	return err;
	return err;
}
}

int __ext4_handle_dirty_super(const char *where, handle_t *handle,
			      struct super_block *sb)
{
	struct buffer_head *bh = EXT4_SB(sb)->s_sbh;
	int err = 0;

	if (ext4_handle_valid(handle)) {
		err = jbd2_journal_dirty_metadata(handle, bh);
		if (err)
			ext4_journal_abort_handle(where, __func__, bh,
						  handle, err);
	} else
		sb->s_dirt = 1;
	return err;
}
+5 −0
Original line number Original line Diff line number Diff line
@@ -141,6 +141,9 @@ int __ext4_journal_get_create_access(const char *where,
int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
				 struct inode *inode, struct buffer_head *bh);
				 struct inode *inode, struct buffer_head *bh);


int __ext4_handle_dirty_super(const char *where, handle_t *handle,
			      struct super_block *sb);

#define ext4_journal_get_undo_access(handle, bh) \
#define ext4_journal_get_undo_access(handle, bh) \
	__ext4_journal_get_undo_access(__func__, (handle), (bh))
	__ext4_journal_get_undo_access(__func__, (handle), (bh))
#define ext4_journal_get_write_access(handle, bh) \
#define ext4_journal_get_write_access(handle, bh) \
@@ -152,6 +155,8 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
	__ext4_journal_get_create_access(__func__, (handle), (bh))
	__ext4_journal_get_create_access(__func__, (handle), (bh))
#define ext4_handle_dirty_metadata(handle, inode, bh) \
#define ext4_handle_dirty_metadata(handle, inode, bh) \
	__ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
	__ext4_handle_dirty_metadata(__func__, (handle), (inode), (bh))
#define ext4_handle_dirty_super(handle, sb) \
	__ext4_handle_dirty_super(__func__, (handle), (sb))


handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
int __ext4_journal_stop(const char *where, handle_t *handle);
int __ext4_journal_stop(const char *where, handle_t *handle);
+1 −1
Original line number Original line Diff line number Diff line
@@ -123,7 +123,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
		if (!IS_ERR(cp)) {
		if (!IS_ERR(cp)) {
			memcpy(sbi->s_es->s_last_mounted, cp,
			memcpy(sbi->s_es->s_last_mounted, cp,
			       sizeof(sbi->s_es->s_last_mounted));
			       sizeof(sbi->s_es->s_last_mounted));
			sb->s_dirt = 1;
			ext4_mark_super_dirty(sb);
		}
		}
	}
	}
	return dquot_file_open(inode, filp);
	return dquot_file_open(inode, filp);
Loading