Skip to content

Commit

Permalink
hfsplus: fix option parsing during remount
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Christoph Hellwig committed Nov 7, 2010
1 parent ff8b16d commit 6f80dfe
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
1 change: 1 addition & 0 deletions fs/hfsplus/hfsplus_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);

Expand Down
26 changes: 26 additions & 0 deletions fs/hfsplus/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 3 additions & 5 deletions fs/hfsplus/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,19 +263,17 @@ 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))) {
printk(KERN_WARNING "hfs: filesystem was not cleanly unmounted, "
"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");
Expand Down

0 comments on commit 6f80dfe

Please sign in to comment.