summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/fs.c25
-rw-r--r--fs/bcachefs/opts.c7
-rw-r--r--fs/bcachefs/opts.h2
3 files changed, 24 insertions, 10 deletions
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index a488dcebc11a..b214d58e94e9 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -1343,7 +1343,7 @@ static int bch2_remount(struct super_block *sb, int *flags, char *data)
opt_set(opts, read_only, (*flags & SB_RDONLY) != 0);
- ret = bch2_parse_mount_opts(&opts, data);
+ ret = bch2_parse_mount_opts(c, &opts, data);
if (ret)
return ret;
@@ -1484,7 +1484,7 @@ static struct dentry *bch2_mount(struct file_system_type *fs_type,
opt_set(opts, read_only, (flags & SB_RDONLY) != 0);
- ret = bch2_parse_mount_opts(&opts, data);
+ ret = bch2_parse_mount_opts(NULL, &opts, data);
if (ret)
return ERR_PTR(ret);
@@ -1507,11 +1507,24 @@ static struct dentry *bch2_mount(struct file_system_type *fs_type,
goto got_sb;
c = bch2_fs_open(devs, nr_devs, opts);
-
- if (!IS_ERR(c))
- sb = sget(fs_type, NULL, bch2_set_super, flags|SB_NOSEC, c);
- else
+ if (IS_ERR(c)) {
sb = ERR_CAST(c);
+ goto got_sb;
+ }
+
+ /* Some options can't be parsed until after the fs is started: */
+ ret = bch2_parse_mount_opts(c, &opts, data);
+ if (ret) {
+ bch2_fs_stop(c);
+ sb = ERR_PTR(ret);
+ goto got_sb;
+ }
+
+ bch2_opts_apply(&c->opts, opts);
+
+ sb = sget(fs_type, NULL, bch2_set_super, flags|SB_NOSEC, c);
+ if (IS_ERR(sb))
+ bch2_fs_stop(c);
got_sb:
kfree(devs_to_fs);
kfree(devs[0]);
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
index afe25cd26c06..97a36ac0beea 100644
--- a/fs/bcachefs/opts.c
+++ b/fs/bcachefs/opts.c
@@ -247,7 +247,7 @@ int bch2_opt_parse(struct bch_fs *c, const struct bch_option *opt,
break;
case BCH_OPT_FN:
if (!c)
- return -EINVAL;
+ return 0;
return opt->parse(c, val, res);
}
@@ -325,7 +325,8 @@ int bch2_opts_check_may_set(struct bch_fs *c)
return 0;
}
-int bch2_parse_mount_opts(struct bch_opts *opts, char *options)
+int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
+ char *options)
{
char *opt, *name, *val;
int ret, id;
@@ -340,7 +341,7 @@ int bch2_parse_mount_opts(struct bch_opts *opts, char *options)
if (id < 0)
goto bad_opt;
- ret = bch2_opt_parse(NULL, &bch2_opt_table[id], val, &v);
+ ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v);
if (ret < 0)
goto bad_val;
} else {
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index 6aaabb24d3ed..1ddb9c57b3a5 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -424,7 +424,7 @@ void bch2_opt_to_text(struct printbuf *, struct bch_fs *,
int bch2_opt_check_may_set(struct bch_fs *, int, u64);
int bch2_opts_check_may_set(struct bch_fs *);
-int bch2_parse_mount_opts(struct bch_opts *, char *);
+int bch2_parse_mount_opts(struct bch_fs *, struct bch_opts *, char *);
/* inode opts: */