hpfs: implement the show_options method
authorMikulas Patocka <mikulas@twibright.com>
Tue, 24 May 2016 20:49:18 +0000 (22:49 +0200)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 23:50:24 +0000 (16:50 -0700)
The HPFS filesystem used generic_show_options to produce string that is
displayed in /proc/mounts.  However, there is a problem that the options
may disappear after remount.  If we mount the filesystem with option1
and then remount it with option2, /proc/mounts should show both option1
and option2, however it only shows option2 because the whole option
string is replaced with replace_mount_options in hpfs_remount_fs.

To fix this bug, implement the hpfs_show_options function that prints
options that are currently selected.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/hpfs/super.c

index 46ad0ef8b4cc7356ec8739e306807e88e2d49e2f..82067ca22f2b909609162c7dc413a93c68aebaa0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/sched.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
+#include <linux/seq_file.h>
 
 /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
 
@@ -453,10 +454,6 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
        int lowercase, eas, chk, errs, chkdsk, timeshift;
        int o;
        struct hpfs_sb_info *sbi = hpfs_sb(s);
-       char *new_opts = kstrdup(data, GFP_KERNEL);
-
-       if (data && !new_opts)
-               return -ENOMEM;
 
        sync_filesystem(s);
 
@@ -493,18 +490,44 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
 
        if (!(*flags & MS_RDONLY)) mark_dirty(s, 1);
 
-       if (new_opts)
-               replace_mount_options(s, new_opts);
-
        hpfs_unlock(s);
        return 0;
 
 out_err:
        hpfs_unlock(s);
-       kfree(new_opts);
        return -EINVAL;
 }
 
+static int hpfs_show_options(struct seq_file *seq, struct dentry *root)
+{
+       struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb);
+
+       seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid));
+       seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid));
+       seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777));
+       if (sbi->sb_lowercase)
+               seq_printf(seq, ",case=lower");
+       if (!sbi->sb_chk)
+               seq_printf(seq, ",check=none");
+       if (sbi->sb_chk == 2)
+               seq_printf(seq, ",check=strict");
+       if (!sbi->sb_err)
+               seq_printf(seq, ",errors=continue");
+       if (sbi->sb_err == 2)
+               seq_printf(seq, ",errors=panic");
+       if (!sbi->sb_chkdsk)
+               seq_printf(seq, ",chkdsk=no");
+       if (sbi->sb_chkdsk == 2)
+               seq_printf(seq, ",chkdsk=always");
+       if (!sbi->sb_eas)
+               seq_printf(seq, ",eas=no");
+       if (sbi->sb_eas == 1)
+               seq_printf(seq, ",eas=ro");
+       if (sbi->sb_timeshift)
+               seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift);
+       return 0;
+}
+
 /* Super operations */
 
 static const struct super_operations hpfs_sops =
@@ -515,7 +538,7 @@ static const struct super_operations hpfs_sops =
        .put_super      = hpfs_put_super,
        .statfs         = hpfs_statfs,
        .remount_fs     = hpfs_remount_fs,
-       .show_options   = generic_show_options,
+       .show_options   = hpfs_show_options,
 };
 
 static int hpfs_fill_super(struct super_block *s, void *options, int silent)
@@ -538,8 +561,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
 
        int o;
 
-       save_mount_options(s, options);
-
        sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
        if (!sbi) {
                return -ENOMEM;