Skip to content

Commit 2ef6c32

Browse files
committed
ext4: avoid updating the superblock on a r/o mount if not needed
This was noticed by a user who noticied that the mtime of a file backing a loopback device was getting bumped when the loopback device is mounted read/only. Note: This doesn't show up when doing a loopback mount of a file directly, via "mount -o ro /tmp/foo.img /mnt", since the loop device is set read-only when mount automatically creates loop device. However, this is noticeable for a LUKS loop device like this: % cryptsetup luksOpen /tmp/foo.img test % mount -o ro /dev/loop0 /mnt ; umount /mnt or, if LUKS is not in use, if the user manually creates the loop device like this: % losetup /dev/loop0 /tmp/foo.img % mount -o ro /dev/loop0 /mnt ; umount /mnt The modified mtime causes rsync to do a rolling checksum scan of the file on the local and remote side, incrementally increasing the time to rsync the not-modified-but-touched image file. Fixes: eee0023 ("ext4: commit super block if fs record error when journal record without error") Cc: [email protected] Link: https://lore.kernel.org/r/ZIauBR7YiV3rVAHL@glitch Reported-by: Sean Greenslade <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 31464ab commit 2ef6c32

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

fs/ext4/super.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5997,19 +5997,27 @@ static int ext4_load_journal(struct super_block *sb,
59975997
err = jbd2_journal_wipe(journal, !really_read_only);
59985998
if (!err) {
59995999
char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
6000+
__le16 orig_state;
6001+
bool changed = false;
60006002

60016003
if (save)
60026004
memcpy(save, ((char *) es) +
60036005
EXT4_S_ERR_START, EXT4_S_ERR_LEN);
60046006
err = jbd2_journal_load(journal);
6005-
if (save)
6007+
if (save && memcmp(((char *) es) + EXT4_S_ERR_START,
6008+
save, EXT4_S_ERR_LEN)) {
60066009
memcpy(((char *) es) + EXT4_S_ERR_START,
60076010
save, EXT4_S_ERR_LEN);
6011+
changed = true;
6012+
}
60086013
kfree(save);
6014+
orig_state = es->s_state;
60096015
es->s_state |= cpu_to_le16(EXT4_SB(sb)->s_mount_state &
60106016
EXT4_ERROR_FS);
6017+
if (orig_state != es->s_state)
6018+
changed = true;
60116019
/* Write out restored error information to the superblock */
6012-
if (!bdev_read_only(sb->s_bdev)) {
6020+
if (changed && !really_read_only) {
60136021
int err2;
60146022
err2 = ext4_commit_super(sb);
60156023
err = err ? : err2;

0 commit comments

Comments
 (0)