fs: push sync_filesystem() down to the file system's remount_fs()
authorTheodore Ts'o <tytso@mit.edu>
Thu, 13 Mar 2014 14:14:33 +0000 (10:14 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 13 Mar 2014 14:14:33 +0000 (10:14 -0400)
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
44 files changed:
fs/adfs/super.c
fs/affs/super.c
fs/befs/linuxvfs.c
fs/btrfs/super.c
fs/cifs/cifsfs.c
fs/coda/inode.c
fs/cramfs/inode.c
fs/debugfs/inode.c
fs/devpts/inode.c
fs/efs/super.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/super.c
fs/f2fs/super.c
fs/fat/inode.c
fs/freevxfs/vxfs_super.c
fs/fuse/inode.c
fs/gfs2/super.c
fs/hfs/super.c
fs/hfsplus/super.c
fs/hpfs/super.c
fs/isofs/inode.c
fs/jffs2/super.c
fs/jfs/super.c
fs/minix/inode.c
fs/ncpfs/inode.c
fs/nfs/super.c
fs/nilfs2/super.c
fs/ntfs/super.c
fs/ocfs2/super.c
fs/openpromfs/inode.c
fs/proc/root.c
fs/pstore/inode.c
fs/qnx4/inode.c
fs/qnx6/inode.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/squashfs/super.c
fs/super.c
fs/sysv/inode.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/xfs_super.c

index 7b3003cb6f1bde4d562d01e85db3455d120c7309..952aeb048349c73ea9a6d9354015163640e47d4b 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return parse_options(sb, data);
 }
index d098731b82ffa794853e66ff0bcb4e05aa59fcbc..307453086c3f84bab8edaff9a201e0da3baad819 100644 (file)
@@ -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);
 
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
 
        memcpy(volume, sbi->s_volume, 32);
index 845d2d690ce2dc2becddef70041a3e6b69440d62..56d70c8a89b0869e08d3e4ff7f3c38d5c6b3d7af 100644 (file)
@@ -913,6 +913,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
 static int
 befs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (!(*flags & MS_RDONLY))
                return -EINVAL;
        return 0;
index 97cc24198554cedd4ada307f2bbe99b80edf4ded..00cd0c57b0b3dd39b59cea127e849eec36e34890 100644 (file)
@@ -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;
        int ret;
 
+       sync_filesystem(sb);
        btrfs_remount_prepare(fs_info);
 
        ret = btrfs_parse_options(root, data);
index 849f6132b327e5e79e35bd4a178784eea001b267..4942c94bf7ee621eae5a6c91fd9f8d43ea158427 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return 0;
 }
index 506de34a4ef33f67929747f28097f83ec84283e6..3f48000ef1a5da3242a65971f1a73e7d1d5d20ae 100644 (file)
@@ -96,6 +96,7 @@ void coda_destroy_inodecache(void)
 
 static int coda_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NOATIME;
        return 0;
 }
index 06610cf94d579a8da72a5d6af53b098ec43e482d..a2759112563c95916fbfed4b60eaa9f2d6535601 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 9c0444cccbe108b245338a0d40a5d702fbe45407..02928a9d00a87c7a359faae79a36b2d332da5cd7 100644 (file)
@@ -218,6 +218,7 @@ static int debugfs_remount(struct super_block *sb, int *flags, char *data)
        int err;
        struct debugfs_fs_info *fsi = sb->s_fs_info;
 
+       sync_filesystem(sb);
        err = debugfs_parse_options(data, &fsi->mount_opts);
        if (err)
                goto fail;
index a726b9f29cb71735eb99ada9367f4348da45eb3d..c71038079b47831bb14b58e375592044906091c3 100644 (file)
@@ -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_mount_opts *opts = &fsi->mount_opts;
 
+       sync_filesystem(sb);
        err = parse_mount_options(data, PARSE_REMOUNT, opts);
 
        /*
index 50215bbd646313fdad24ae3b521af017b834bcf9..103bbd820b87c38f9923382231299e0e51360336 100644 (file)
@@ -114,6 +114,7 @@ static void destroy_inodecache(void)
 
 static int efs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 20d6697bd6386560a679dda5e8b8592a65d63798..d260115c0350e91be14eca760b813032e5325fca 100644 (file)
@@ -1254,6 +1254,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data)
        unsigned long old_sb_flags;
        int err;
 
+       sync_filesystem(sb);
        spin_lock(&sbi->s_lock);
 
        /* Store the old options */
index 37fd31ed16e781fd525773e2f9dc0a2e7b274ab0..95c6c5a6d0c56e20fe6bc2374dc8a3bed5da2b72 100644 (file)
@@ -2649,6 +2649,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
        int i;
 #endif
 
+       sync_filesystem(sb);
+
        /* Store the original options */
        old_sb_flags = sb->s_flags;
        old_opts.s_mount_opt = sbi->s_mount_opt;
index 7a829f750235abdda481d1d67101f6426fa96464..a5f1170048bd479f1069b4f255a0bba3c62ac07b 100644 (file)
@@ -4765,6 +4765,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 #endif
        char *orig_data = kstrdup(data, GFP_KERNEL);
 
+       sync_filesystem(sb);
+
        /* Store the original options */
        old_sb_flags = sb->s_flags;
        old_opts.s_mount_opt = sbi->s_mount_opt;
index 1a85f83abd53262f9f1e7c5b71cb38919e85ab22..856bdf994c0a4262f802bf3fdf2fa3ed7b8167c7 100644 (file)
@@ -568,6 +568,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
        struct f2fs_mount_info org_mount_opt;
        int err, active_logs;
 
+       sync_filesystem(sb);
+
        /*
         * Save the old mount options in case we
         * need to restore them.
index 854b578f6695eae6e0ef25d7af4dcdc8546d6044..343e477c6dcb1fe2e83324ffd1f7a86ce5a3d743 100644 (file)
@@ -635,6 +635,8 @@ static int fat_remount(struct super_block *sb, int *flags, char *data)
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
        *flags |= MS_NODIRATIME | (sbi->options.isvfat ? 0 : MS_NOATIME);
 
+       sync_filesystem(sb);
+
        /* make sure we update state on remount. */
        new_rdonly = *flags & MS_RDONLY;
        if (new_rdonly != (sb->s_flags & MS_RDONLY)) {
index e37eb274e492a9dfd36d4f717d363b6932ae90b5..7ca8c75d50d3fdc5f9079599465e04f99058d45d 100644 (file)
@@ -124,6 +124,7 @@ vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
 
 static int vxfs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index d468643a68b2f4b9b9cf7ca38de529db096f89ed..ecdb255d086da871b5c092398f74644d04dfe2a0 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        if (*flags & MS_MANDLOCK)
                return -EINVAL;
 
index 60f60f6181f337cd86452403132e9d48de2a9034..4c6dd50831baf51df3731b1bd388337620bb45d9 100644 (file)
@@ -1175,6 +1175,8 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
        struct gfs2_tune *gt = &sdp->sd_tune;
        int error;
 
+       sync_filesystem(sb);
+
        spin_lock(&gt->gt_spin);
        args.ar_commit = gt->gt_logd_secs;
        args.ar_quota_quantum = gt->gt_quota_quantum;
index 2d2039e754cdb8e7182053ea5666ed64d14ca488..eee7206c38d18e1a3d3b1697fd429763e3fe9f5b 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
index 80875aa640efc0f5831daa3fb919940d8d85e25b..8eb787b52c058a607c10dca255232901d7a1a4de 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
        if (!(*flags & MS_RDONLY)) {
index 4534ff688b767e56b08302b6cedb199cdafeff4d..fe3463a432365f5ba3596dd4d1db0f7bb1d95c6f 100644 (file)
@@ -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);
        char *new_opts = kstrdup(data, GFP_KERNEL);
        
+       sync_filesystem(s);
+
        *flags |= MS_NOATIME;
        
        hpfs_lock(s);
index 4a9e10ea13f2910570e989bdb2746fcc9ab796b1..6af66ee56390793ed3b1f718f2cb07cba8b92a50 100644 (file)
@@ -117,6 +117,7 @@ static void destroy_inodecache(void)
 
 static int isofs_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        if (!(*flags & MS_RDONLY))
                return -EROFS;
        return 0;
index 0defb1cc2a3520d6f5f67cc880f91d0e9fe5b244..0918f0e2e26608467356235c4267c336cccee87c 100644 (file)
@@ -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);
        int err;
 
+       sync_filesystem(sb);
        err = jffs2_parse_options(c, data);
        if (err)
                return -EINVAL;
index e2b7483444fd0dc7163cf1d4ab651917b824965e..97f7fda51890b28d11bad813bd1d3c03bc331c16 100644 (file)
@@ -418,6 +418,7 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
        int flag = JFS_SBI(sb)->flag;
        int ret;
 
+       sync_filesystem(sb);
        if (!parse_options(data, sb, &newLVSize, &flag)) {
                return -EINVAL;
        }
index 0332109162a53f614c3c169297e25faf4bb06852..dcdc2989370df416a04ae7f6e20a1ba644a5470f 100644 (file)
@@ -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_super_block * ms;
 
+       sync_filesystem(sb);
        ms = sbi->s_ms;
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
                return 0;
index 2cf2ebecb55f30993eda3dd4dac1dca5b2aa3584..5f86e8080178893f7fe8ff2e1f2cfd7d2d51c406 100644 (file)
@@ -99,6 +99,7 @@ static void destroy_inodecache(void)
 
 static int ncp_remount(struct super_block *sb, int *flags, char* data)
 {
+       sync_filesystem(sb);
        *flags |= MS_NODIRATIME;
        return 0;
 }
index 910ed906eb82f0465eb9317f8c8d4c7640bc7e17..2cb56943e2322a00e65c433d0f592ae6f32c4360 100644 (file)
@@ -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;
        u32 nfsvers = nfss->nfs_client->rpc_ops->version;
 
+       sync_filesystem(sb);
+
        /*
         * Userspace mount programs that send binary options generally send
         * them populated with default values. We have no way to know which
index 7ac2a122ca1dd1ce042005600d1396990d0ec3a4..8c532b2ca3aba1c1a4c6e162641e3eb7d009f91c 100644 (file)
@@ -1129,6 +1129,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
        unsigned long old_mount_opt;
        int err;
 
+       sync_filesystem(sb);
        old_sb_flags = sb->s_flags;
        old_mount_opt = nilfs->ns_mount_opt;
 
index 82650d52d9168ee4f1e1b4282813afdaca5c7ec6..bd5610d482423a0ddf8efaf865f368d66d005e9f 100644 (file)
@@ -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);
 
+       sync_filesystem(sb);
+
 #ifndef NTFS_RW
        /* For read-only compiled driver, enforce read-only flag. */
        *flags |= MS_RDONLY;
index 49d84f80f36ce96ca61d5c5abd81e915aff40635..5f9bf8f9dfa79e1cc2b60b890694d1c10e1bbe8b 100644 (file)
@@ -631,6 +631,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
        struct ocfs2_super *osb = OCFS2_SB(sb);
        u32 tmp;
 
+       sync_filesystem(sb);
+
        if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
            !ocfs2_check_set_options(sb, &parsed_options)) {
                ret = -EINVAL;
index 8c0ceb8dd1f709a6b3b6427eabc28718f23f9a50..15e4500cda3ee28f56957d03adf120ae8d9f73fb 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_NOATIME;
        return 0;
 }
index 87dbcbef7fe4b3535d4bfdcbc7590af24d3d5f0a..ac823a85cf6e5675b6ff3318784c6c8f9ea176ef 100644 (file)
@@ -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)
 {
        struct pid_namespace *pid = sb->s_fs_info;
+
+       sync_filesystem(sb);
        return !proc_parse_options(data, pid);
 }
 
index 12823845d32490d220d795ee46e1a328491a1585..192297b0090da25026bb5ee9b8033b48ccca927e 100644 (file)
@@ -249,6 +249,7 @@ static void parse_options(char *options)
 
 static int pstore_remount(struct super_block *sb, int *flags, char *data)
 {
+       sync_filesystem(sb);
        parse_options(data);
 
        return 0;
index 89558810381c497389c184856d30efd0a2ce9717..c4bcb778886e5c79c4dcc9381cf13f0a76358838 100644 (file)
@@ -44,6 +44,7 @@ static int qnx4_remount(struct super_block *sb, int *flags, char *data)
 {
        struct qnx4_sb_info *qs;
 
+       sync_filesystem(sb);
        qs = qnx4_sb(sb);
        qs->Version = QNX4_VERSION;
        *flags |= MS_RDONLY;
index 8d941edfefa156bedb93a1a074ccda0e9a042fad..65cdaab3ed49d554e4d618202e4d41d11718c714 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 2c803353f8ac4f70099f7cef6a590c46556c21d6..abf2b76c0d198768a0c0aef2e1eeb7241ab1beaa 100644 (file)
@@ -1319,6 +1319,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
        int i;
 #endif
 
+       sync_filesystem(s);
        reiserfs_write_lock(s);
 
 #ifdef CONFIG_QUOTA
index d8418782862b60fe2b96b4bd131281417c2adc24..ef90e8bca95ac77e6808a300eb053d36911db523 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 202df6312d4e8517a63bb9ff10b385738e54ab6e..031c8d67fd5178bb5afca2b04c71637254b46873 100644 (file)
@@ -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)
 {
+       sync_filesystem(sb);
        *flags |= MS_RDONLY;
        return 0;
 }
index 80d5cf2ca76518a450a31cb7cad340794a525ed8..e9dc3c3fe159cc2e59bfb27f0beb8bd30e92188b 100644 (file)
@@ -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) {
                retval = sb->s_op->remount_fs(sb, &flags, data);
                if (retval) {
index c327d4ee1235494e05ae1587b86ca357577b2292..4742e58f3fc520328a965b7a512fbcb3d0ec02a9 100644 (file)
@@ -60,6 +60,7 @@ static int sysv_remount(struct super_block *sb, int *flags, char *data)
 {
        struct sysv_sb_info *sbi = SYSV_SB(sb);
 
+       sync_filesystem(sb);
        if (sbi->s_forced_ro)
                *flags |= MS_RDONLY;
        return 0;
index 5ded8490c0c66cca3a6dea286aec8e700bc24e44..e1598abd74752c25fd12257eef3a1ba576893dda 100644 (file)
@@ -1827,6 +1827,7 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
        int err;
        struct ubifs_info *c = sb->s_fs_info;
 
+       sync_filesystem(sb);
        dbg_gen("old flags %#lx, new flags %#x", sb->s_flags, *flags);
 
        err = ubifs_parse_options(c, data, 1);
index 3306b9f69bedbb5ba2cb4e11b180b2b75e947dd5..64f2b7334d08bf41f6ec9ed0910393eb680d9fbc 100644 (file)
@@ -646,6 +646,7 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
        int error = 0;
        struct logicalVolIntegrityDescImpUse *lvidiu = udf_sb_lvidiu(sb);
 
+       sync_filesystem(sb);
        if (lvidiu) {
                int write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
                if (write_rev > UDF_MAX_WRITE_VERSION && !(*flags & MS_RDONLY))
index 329f2f53b7ed655b2ef525331f7c75a714d58de9..b8c6791f046fbe4195d97697bbe8a6ba29be03a0 100644 (file)
@@ -1280,6 +1280,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
        unsigned new_mount_opt, ufstype;
        unsigned flags;
 
+       sync_filesystem(sb);
        lock_ufs(sb);
        mutex_lock(&UFS_SB(sb)->s_lock);
        uspi = UFS_SB(sb)->s_uspi;
index f317488263dd975eb85eb44d9746abfb974ef46f..aaa3eca3f234ce72f6fadc74d3835a26c67c4314 100644 (file)
@@ -1197,6 +1197,7 @@ xfs_fs_remount(
        char                    *p;
        int                     error;
 
+       sync_filesystem(sb);
        while ((p = strsep(&options, ",")) != NULL) {
                int token;