Skip to content

Commit f25391e

Browse files
Lukas Czernertytso
authored andcommitted
ext4: handle option set by mount flags correctly
Currently there is a problem with mount options that can be both set by vfs using mount flags or by a string parsing in ext4. i_version/iversion options gets lost after remount, for example $ mount -o i_version /dev/pmem0 /mnt $ grep pmem0 /proc/self/mountinfo | grep i_version 310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,seclabel,i_version $ mount -o remount,ro /mnt $ grep pmem0 /proc/self/mountinfo | grep i_version nolazytime gets ignored by ext4 on remount, for example $ mount -o lazytime /dev/pmem0 /mnt $ grep pmem0 /proc/self/mountinfo | grep lazytime 310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,lazytime,seclabel $ mount -o remount,nolazytime /mnt $ grep pmem0 /proc/self/mountinfo | grep lazytime 310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,lazytime,seclabel Fix it by applying the SB_LAZYTIME and SB_I_VERSION flags from *flags to s_flags before we parse the option and use the resulting state of the same flags in *flags at the end of successful remount. Signed-off-by: Lukas Czerner <[email protected]> Reviewed-by: Ritesh Harjani <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 60ed633 commit f25391e

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

fs/ext4/super.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5512,7 +5512,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
55125512
{
55135513
struct ext4_super_block *es;
55145514
struct ext4_sb_info *sbi = EXT4_SB(sb);
5515-
unsigned long old_sb_flags;
5515+
unsigned long old_sb_flags, vfs_flags;
55165516
struct ext4_mount_options old_opts;
55175517
int enable_quota = 0;
55185518
ext4_group_t g;
@@ -5555,6 +5555,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
55555555
if (sbi->s_journal && sbi->s_journal->j_task->io_context)
55565556
journal_ioprio = sbi->s_journal->j_task->io_context->ioprio;
55575557

5558+
/*
5559+
* Some options can be enabled by ext4 and/or by VFS mount flag
5560+
* either way we need to make sure it matches in both *flags and
5561+
* s_flags. Copy those selected flags from *flags to s_flags
5562+
*/
5563+
vfs_flags = SB_LAZYTIME | SB_I_VERSION;
5564+
sb->s_flags = (sb->s_flags & ~vfs_flags) | (*flags & vfs_flags);
5565+
55585566
if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
55595567
err = -EINVAL;
55605568
goto restore_opts;
@@ -5608,9 +5616,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
56085616
set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
56095617
}
56105618

5611-
if (*flags & SB_LAZYTIME)
5612-
sb->s_flags |= SB_LAZYTIME;
5613-
56145619
if ((bool)(*flags & SB_RDONLY) != sb_rdonly(sb)) {
56155620
if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
56165621
err = -EROFS;
@@ -5758,7 +5763,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
57585763
}
57595764
#endif
57605765

5761-
*flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
5766+
/*
5767+
* Some options can be enabled by ext4 and/or by VFS mount flag
5768+
* either way we need to make sure it matches in both *flags and
5769+
* s_flags. Copy those selected flags from s_flags to *flags
5770+
*/
5771+
*flags = (*flags & ~vfs_flags) | (sb->s_flags & vfs_flags);
5772+
57625773
ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
57635774
kfree(orig_data);
57645775
return 0;

0 commit comments

Comments
 (0)