fs: push sync_filesystem() down to the file system's remount_fs()

Previously, the no-op "mount -o mount /dev/xxx" operation when the
file system is already mounted read-write causes an implied,
unconditional syncfs().  This seems pretty stupid, and it's certainly
documented or guaraunteed to do this, nor is it particularly useful,
except in the case where the file system was mounted rw and is getting
remounted read-only.

However, it's possible that there might be some file systems that are
actually depending on this behavior.  In most file systems, it's
probably fine to only call sync_filesystem() when transitioning from
read-write to read-only, and there are some file systems where this is
not needed at all (for example, for a pseudo-filesystem or something
like romfs).

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: linux-fsdevel@vger.kernel.org
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Artem Bityutskiy <dedekind1@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Evgeniy Dushistov <dushistov@mail.ru>
Cc: Jan Kara <jack@suse.cz>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Anders Larsen <al@alarsen.net>
Cc: Phillip Lougher <phillip@squashfs.org.uk>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: Petr Vandrovec <petr@vandrovec.name>
Cc: xfs@oss.sgi.com
Cc: linux-btrfs@vger.kernel.org
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Cc: codalist@coda.cs.cmu.edu
Cc: linux-ext4@vger.kernel.org
Cc: linux-f2fs-devel@lists.sourceforge.net
Cc: fuse-devel@lists.sourceforge.net
Cc: cluster-devel@redhat.com
Cc: linux-mtd@lists.infradead.org
Cc: jfs-discussion@lists.sourceforge.net
Cc: linux-nfs@vger.kernel.org
Cc: linux-nilfs@vger.kernel.org
Cc: linux-ntfs-dev@lists.sourceforge.net
Cc: ocfs2-devel@oss.oracle.com
Cc: reiserfs-devel@vger.kernel.org
This commit is contained in:
Theodore Ts'o 2014-03-13 10:14:33 -04:00
Родитель 66a4cb187b
Коммит 02b9984d64
44 изменённых файлов: 53 добавлений и 2 удалений

Просмотреть файл

@ -212,6 +212,7 @@ static int parse_options(struct super_block *sb, char *options)
static int adfs_remount(struct super_block *sb, int *flags, char *data) static int adfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_NODIRATIME; *flags |= MS_NODIRATIME;
return parse_options(sb, data); return parse_options(sb, data);
} }

Просмотреть файл

@ -530,6 +530,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data); pr_debug("AFFS: remount(flags=0x%x,opts=\"%s\")\n",*flags,data);
sync_filesystem(sb);
*flags |= MS_NODIRATIME; *flags |= MS_NODIRATIME;
memcpy(volume, sbi->s_volume, 32); memcpy(volume, sbi->s_volume, 32);

Просмотреть файл

@ -913,6 +913,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
static int static int
befs_remount(struct super_block *sb, int *flags, char *data) befs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
if (!(*flags & MS_RDONLY)) if (!(*flags & MS_RDONLY))
return -EINVAL; return -EINVAL;
return 0; return 0;

Просмотреть файл

@ -1381,6 +1381,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
unsigned int old_metadata_ratio = fs_info->metadata_ratio; unsigned int old_metadata_ratio = fs_info->metadata_ratio;
int ret; int ret;
sync_filesystem(sb);
btrfs_remount_prepare(fs_info); btrfs_remount_prepare(fs_info);
ret = btrfs_parse_options(root, data); ret = btrfs_parse_options(root, data);

Просмотреть файл

@ -541,6 +541,7 @@ static int cifs_show_stats(struct seq_file *s, struct dentry *root)
static int cifs_remount(struct super_block *sb, int *flags, char *data) static int cifs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_NODIRATIME; *flags |= MS_NODIRATIME;
return 0; return 0;
} }

Просмотреть файл

@ -96,6 +96,7 @@ void coda_destroy_inodecache(void)
static int coda_remount(struct super_block *sb, int *flags, char *data) static int coda_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_NOATIME; *flags |= MS_NOATIME;
return 0; return 0;
} }

Просмотреть файл

@ -244,6 +244,7 @@ static void cramfs_kill_sb(struct super_block *sb)
static int cramfs_remount(struct super_block *sb, int *flags, char *data) static int cramfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -218,6 +218,7 @@ static int debugfs_remount(struct super_block *sb, int *flags, char *data)
int err; int err;
struct debugfs_fs_info *fsi = sb->s_fs_info; struct debugfs_fs_info *fsi = sb->s_fs_info;
sync_filesystem(sb);
err = debugfs_parse_options(data, &fsi->mount_opts); err = debugfs_parse_options(data, &fsi->mount_opts);
if (err) if (err)
goto fail; goto fail;

Просмотреть файл

@ -313,6 +313,7 @@ static int devpts_remount(struct super_block *sb, int *flags, char *data)
struct pts_fs_info *fsi = DEVPTS_SB(sb); struct pts_fs_info *fsi = DEVPTS_SB(sb);
struct pts_mount_opts *opts = &fsi->mount_opts; struct pts_mount_opts *opts = &fsi->mount_opts;
sync_filesystem(sb);
err = parse_mount_options(data, PARSE_REMOUNT, opts); err = parse_mount_options(data, PARSE_REMOUNT, opts);
/* /*

Просмотреть файл

@ -114,6 +114,7 @@ static void destroy_inodecache(void)
static int efs_remount(struct super_block *sb, int *flags, char *data) static int efs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -1254,6 +1254,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
unsigned long old_sb_flags; unsigned long old_sb_flags;
int err; int err;
sync_filesystem(sb);
spin_lock(&sbi->s_lock); spin_lock(&sbi->s_lock);
/* Store the old options */ /* Store the old options */

Просмотреть файл

@ -2649,6 +2649,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
int i; int i;
#endif #endif
sync_filesystem(sb);
/* Store the original options */ /* Store the original options */
old_sb_flags = sb->s_flags; old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt; old_opts.s_mount_opt = sbi->s_mount_opt;

Просмотреть файл

@ -4765,6 +4765,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
#endif #endif
char *orig_data = kstrdup(data, GFP_KERNEL); char *orig_data = kstrdup(data, GFP_KERNEL);
sync_filesystem(sb);
/* Store the original options */ /* Store the original options */
old_sb_flags = sb->s_flags; old_sb_flags = sb->s_flags;
old_opts.s_mount_opt = sbi->s_mount_opt; old_opts.s_mount_opt = sbi->s_mount_opt;

Просмотреть файл

@ -568,6 +568,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
struct f2fs_mount_info org_mount_opt; struct f2fs_mount_info org_mount_opt;
int err, active_logs; int err, active_logs;
sync_filesystem(sb);
/* /*
* Save the old mount options in case we * Save the old mount options in case we
* need to restore them. * need to restore them.

Просмотреть файл

@ -635,6 +635,8 @@ static int fat_remount(struct super_block *sb, int *flags, char *data)
struct msdos_sb_info *sbi = MSDOS_SB(sb); struct msdos_sb_info *sbi = MSDOS_SB(sb);
*flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME); *flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);
sync_filesystem(sb);
/* make sure we update state on remount. */ /* make sure we update state on remount. */
new_rdonly = *flags & MS_RDONLY; new_rdonly = *flags & MS_RDONLY;
if (new_rdonly != (sb->s_flags & MS_RDONLY)) { if (new_rdonly != (sb->s_flags & MS_RDONLY)) {

Просмотреть файл

@ -124,6 +124,7 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
static int vxfs_remount(struct super_block *sb, int *flags, char *data) static int vxfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -135,6 +135,7 @@ static void fuse_evict_inode(struct inode *inode)
static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) static int fuse_remount_fs(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
if (*flags & MS_MANDLOCK) if (*flags & MS_MANDLOCK)
return -EINVAL; return -EINVAL;

Просмотреть файл

@ -1175,6 +1175,8 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
struct gfs2_tune *gt = &sdp->sd_tune; struct gfs2_tune *gt = &sdp->sd_tune;
int error; int error;
sync_filesystem(sb);
spin_lock(&gt->gt_spin); spin_lock(&gt->gt_spin);
args.ar_commit = gt->gt_logd_secs; args.ar_commit = gt->gt_logd_secs;
args.ar_quota_quantum = gt->gt_quota_quantum; args.ar_quota_quantum = gt->gt_quota_quantum;

Просмотреть файл

@ -112,6 +112,7 @@ static int hfs_statfs(struct dentry *dentry, struct kstatfs *buf)
static int hfs_remount(struct super_block *sb, int *flags, char *data) static int hfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_NODIRATIME; *flags |= MS_NODIRATIME;
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0; return 0;

Просмотреть файл

@ -323,6 +323,7 @@ static int hfsplus_statfs(struct dentry *dentry, struct kstatfs *buf)
static int hfsplus_remount(struct super_block *sb, int *flags, char *data) static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0; return 0;
if (!(*flags & MS_RDONLY)) { if (!(*flags & MS_RDONLY)) {

Просмотреть файл

@ -421,6 +421,8 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
struct hpfs_sb_info *sbi = hpfs_sb(s); struct hpfs_sb_info *sbi = hpfs_sb(s);
char *new_opts = kstrdup(data, GFP_KERNEL); char *new_opts = kstrdup(data, GFP_KERNEL);
sync_filesystem(s);
*flags |= MS_NOATIME; *flags |= MS_NOATIME;
hpfs_lock(s); hpfs_lock(s);

Просмотреть файл

@ -117,6 +117,7 @@ static void destroy_inodecache(void)
static int isofs_remount(struct super_block *sb, int *flags, char *data) static int isofs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
if (!(*flags & MS_RDONLY)) if (!(*flags & MS_RDONLY))
return -EROFS; return -EROFS;
return 0; return 0;

Просмотреть файл

@ -243,6 +243,7 @@ static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
int err; int err;
sync_filesystem(sb);
err = jffs2_parse_options(c, data); err = jffs2_parse_options(c, data);
if (err) if (err)
return -EINVAL; return -EINVAL;

Просмотреть файл

@ -418,6 +418,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
int flag = JFS_SBI(sb)->flag; int flag = JFS_SBI(sb)->flag;
int ret; int ret;
sync_filesystem(sb);
if (!parse_options(data, sb, &newLVSize, &flag)) { if (!parse_options(data, sb, &newLVSize, &flag)) {
return -EINVAL; return -EINVAL;
} }

Просмотреть файл

@ -123,6 +123,7 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
struct minix_sb_info * sbi = minix_sb(sb); struct minix_sb_info * sbi = minix_sb(sb);
struct minix_super_block * ms; struct minix_super_block * ms;
sync_filesystem(sb);
ms = sbi->s_ms; ms = sbi->s_ms;
if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
return 0; return 0;

Просмотреть файл

@ -99,6 +99,7 @@ static void destroy_inodecache(void)
static int ncp_remount(struct super_block *sb, int *flags, char* data) static int ncp_remount(struct super_block *sb, int *flags, char* data)
{ {
sync_filesystem(sb);
*flags |= MS_NODIRATIME; *flags |= MS_NODIRATIME;
return 0; return 0;
} }

Просмотреть файл

@ -2215,6 +2215,8 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data; struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
u32 nfsvers = nfss->nfs_client->rpc_ops->version; u32 nfsvers = nfss->nfs_client->rpc_ops->version;
sync_filesystem(sb);
/* /*
* Userspace mount programs that send binary options generally send * Userspace mount programs that send binary options generally send
* them populated with default values. We have no way to know which * them populated with default values. We have no way to know which

Просмотреть файл

@ -1129,6 +1129,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
unsigned long old_mount_opt; unsigned long old_mount_opt;
int err; int err;
sync_filesystem(sb);
old_sb_flags = sb->s_flags; old_sb_flags = sb->s_flags;
old_mount_opt = nilfs->ns_mount_opt; old_mount_opt = nilfs->ns_mount_opt;

Просмотреть файл

@ -468,6 +468,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
ntfs_debug("Entering with remount options string: %s", opt); ntfs_debug("Entering with remount options string: %s", opt);
sync_filesystem(sb);
#ifndef NTFS_RW #ifndef NTFS_RW
/* For read-only compiled driver, enforce read-only flag. */ /* For read-only compiled driver, enforce read-only flag. */
*flags |= MS_RDONLY; *flags |= MS_RDONLY;

Просмотреть файл

@ -631,6 +631,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
struct ocfs2_super *osb = OCFS2_SB(sb); struct ocfs2_super *osb = OCFS2_SB(sb);
u32 tmp; u32 tmp;
sync_filesystem(sb);
if (!ocfs2_parse_options(sb, data, &parsed_options, 1) || if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
!ocfs2_check_set_options(sb, &parsed_options)) { !ocfs2_check_set_options(sb, &parsed_options)) {
ret = -EINVAL; ret = -EINVAL;

Просмотреть файл

@ -368,6 +368,7 @@ static struct inode *openprom_iget(struct super_block *sb, ino_t ino)
static int openprom_remount(struct super_block *sb, int *flags, char *data) static int openprom_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_NOATIME; *flags |= MS_NOATIME;
return 0; return 0;
} }

Просмотреть файл

@ -92,6 +92,8 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
int proc_remount(struct super_block *sb, int *flags, char *data) int proc_remount(struct super_block *sb, int *flags, char *data)
{ {
struct pid_namespace *pid = sb->s_fs_info; struct pid_namespace *pid = sb->s_fs_info;
sync_filesystem(sb);
return !proc_parse_options(data, pid); return !proc_parse_options(data, pid);
} }

Просмотреть файл

@ -249,6 +249,7 @@ static void parse_options(char *options)
static int pstore_remount(struct super_block *sb, int *flags, char *data) static int pstore_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
parse_options(data); parse_options(data);
return 0; return 0;

Просмотреть файл

@ -44,6 +44,7 @@ static int qnx4_remount(struct super_block *sb, int *flags, char *data)
{ {
struct qnx4_sb_info *qs; struct qnx4_sb_info *qs;
sync_filesystem(sb);
qs = qnx4_sb(sb); qs = qnx4_sb(sb);
qs->Version = QNX4_VERSION; qs->Version = QNX4_VERSION;
*flags |= MS_RDONLY; *flags |= MS_RDONLY;

Просмотреть файл

@ -55,6 +55,7 @@ static int qnx6_show_options(struct seq_file *seq, struct dentry *root)
static int qnx6_remount(struct super_block *sb, int *flags, char *data) static int qnx6_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -1319,6 +1319,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
int i; int i;
#endif #endif
sync_filesystem(s);
reiserfs_write_lock(s); reiserfs_write_lock(s);
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA

Просмотреть файл

@ -432,6 +432,7 @@ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
*/ */
static int romfs_remount(struct super_block *sb, int *flags, char *data) static int romfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -371,6 +371,7 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
static int squashfs_remount(struct super_block *sb, int *flags, char *data) static int squashfs_remount(struct super_block *sb, int *flags, char *data)
{ {
sync_filesystem(sb);
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;
} }

Просмотреть файл

@ -719,8 +719,6 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
} }
} }
sync_filesystem(sb);
if (sb->s_op->remount_fs) { if (sb->s_op->remount_fs) {
retval = sb->s_op->remount_fs(sb, &flags, data); retval = sb->s_op->remount_fs(sb, &flags, data);
if (retval) { if (retval) {

Просмотреть файл

@ -60,6 +60,7 @@ static int sysv_remount(struct super_block *sb, int *flags, char *data)
{ {
struct sysv_sb_info *sbi = SYSV_SB(sb); struct sysv_sb_info *sbi = SYSV_SB(sb);
sync_filesystem(sb);
if (sbi->s_forced_ro) if (sbi->s_forced_ro)
*flags |= MS_RDONLY; *flags |= MS_RDONLY;
return 0; return 0;

Просмотреть файл

@ -1827,6 +1827,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
int err; int err;
struct ubifs_info *c = sb->s_fs_info; struct ubifs_info *c = sb->s_fs_info;
sync_filesystem(sb);
dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags); dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags);
err = ubifs_parse_options(c, data, 1); err = ubifs_parse_options(c, data, 1);

Просмотреть файл

@ -646,6 +646,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
int error = 0; int error = 0;
struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb); struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
sync_filesystem(sb);
if (lvidiu) { if (lvidiu) {
int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev); int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY)) if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY))

Просмотреть файл

@ -1280,6 +1280,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
unsigned new_mount_opt, ufstype; unsigned new_mount_opt, ufstype;
unsigned flags; unsigned flags;
sync_filesystem(sb);
lock_ufs(sb); lock_ufs(sb);
mutex_lock(&UFS_SB(sb)->s_lock); mutex_lock(&UFS_SB(sb)->s_lock);
uspi = UFS_SB(sb)->s_uspi; uspi = UFS_SB(sb)->s_uspi;

Просмотреть файл

@ -1197,6 +1197,7 @@ xfs_fs_remount(
char *p; char *p;
int error; int error;
sync_filesystem(sb);
while ((p = strsep(&options, ",")) != NULL) { while ((p = strsep(&options, ",")) != NULL) {
int token; int token;