]> Pileus Git - ~andy/linux/commitdiff
hfsplus: fix option parsing during remount
authorChristoph Hellwig <hch@tuxera.com>
Sun, 7 Nov 2010 22:01:17 +0000 (23:01 +0100)
committerChristoph Hellwig <hch@lst.de>
Sun, 7 Nov 2010 22:01:17 +0000 (23:01 +0100)
hfsplus only actually uses the force option during remount, but it uses
the full option parser with a fake superblock to do so.  This means remount
will fail if any nls option is set (which happens frequently with older
mount tools), even if it is the same.

Fix this by adding a simpler version of the parser that only parses the force
option for remount.

Signed-off-by: Christoph Hellwig <hch@tuxera.com>
fs/hfsplus/hfsplus_fs.h
fs/hfsplus/options.c
fs/hfsplus/super.c

index cb3653efb57a2dcf2285a19fcb7262cb7a1ba509..f07aa640c27d30f0eac8a51bc17c0ebfd192afbe 100644 (file)
@@ -362,6 +362,7 @@ ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
 
 /* options.c */
 int hfsplus_parse_options(char *, struct hfsplus_sb_info *);
+int hfsplus_parse_options_remount(char *input, int *force);
 void hfsplus_fill_defaults(struct hfsplus_sb_info *);
 int hfsplus_show_options(struct seq_file *, struct vfsmount *);
 
index f9ab276a4d8de9e15d2acf49a358da1a9ff10fe6..43b02b5525eb2898d4e0df1f91039a8d39b89706 100644 (file)
@@ -65,6 +65,32 @@ static inline int match_fourchar(substring_t *arg, u32 *result)
        return 0;
 }
 
+int hfsplus_parse_options_remount(char *input, int *force)
+{
+       char *p;
+       substring_t args[MAX_OPT_ARGS];
+       int token;
+
+       if (!input)
+               return 0;
+
+       while ((p = strsep(&input, ",")) != NULL) {
+               if (!*p)
+                       continue;
+
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case opt_force:
+                       *force = 1;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return 1;
+}
+
 /* Parse options from mount. Returns 0 on failure */
 /* input is the options passed to mount() as a string */
 int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
index 52cc746d3ba36dd7a6ae8c2ab366d8469131456f..1c356a2fba01a19477ce68d71acd430c55bb342c 100644 (file)
@@ -263,11 +263,9 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
                return 0;
        if (!(*flags & MS_RDONLY)) {
                struct hfsplus_vh *vhdr = HFSPLUS_SB(sb)->s_vhdr;
-               struct hfsplus_sb_info sbi;
+               int force = 0;
 
-               memset(&sbi, 0, sizeof(struct hfsplus_sb_info));
-               sbi.nls = HFSPLUS_SB(sb)->nls;
-               if (!hfsplus_parse_options(data, &sbi))
+               if (!hfsplus_parse_options_remount(data, &force))
                        return -EINVAL;
 
                if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
@@ -275,7 +273,7 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
                               "running fsck.hfsplus is recommended.  leaving read-only.\n");
                        sb->s_flags |= MS_RDONLY;
                        *flags |= MS_RDONLY;
-               } else if (test_bit(HFSPLUS_SB_FORCE, &sbi.flags)) {
+               } else if (force) {
                        /* nothing */
                } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
                        printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n");