bcachefs: Add an "ignore unknown" option to bch2_parse_mount_opts()

To be used by the mount helper in userspace, where we still have options
to be parsed by other layers.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2025-03-25 13:19:40 -04:00
parent daa771332e
commit a7cdf2276e
4 changed files with 28 additions and 29 deletions

View File

@ -2179,7 +2179,7 @@ static int bch2_fs_get_tree(struct fs_context *fc)
/* Some options can't be parsed until after the fs is started: */
opts = bch2_opts_empty();
ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf);
ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf, false);
if (ret)
goto err_stop_fs;
@ -2334,6 +2334,8 @@ static int bch2_fs_parse_param(struct fs_context *fc,
int ret = bch2_parse_one_mount_opt(c, &opts->opts,
&opts->parse_later, param->key,
param->string);
if (ret)
pr_err("Error parsing option %s: %s", param->key, bch2_err_str(ret));
return bch2_err_class(ret);
}

View File

@ -3021,7 +3021,7 @@ long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_arg)
if (arg.opts) {
char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
ret = PTR_ERR_OR_ZERO(optstr) ?:
bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr);
bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr, false);
if (!IS_ERR(optstr))
kfree(optstr);
@ -3129,7 +3129,7 @@ long bch2_ioctl_fsck_online(struct bch_fs *c, struct bch_ioctl_fsck_online arg)
char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
ret = PTR_ERR_OR_ZERO(optstr) ?:
bch2_parse_mount_opts(c, &thr->opts, NULL, optstr);
bch2_parse_mount_opts(c, &thr->opts, NULL, optstr, false);
if (!IS_ERR(optstr))
kfree(optstr);

View File

@ -549,14 +549,15 @@ int bch2_parse_one_mount_opt(struct bch_fs *c, struct bch_opts *opts,
goto bad_opt;
ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err);
if (ret == -BCH_ERR_option_needs_open_fs && parse_later) {
prt_printf(parse_later, "%s=%s,", name, val);
if (parse_later->allocation_failure) {
ret = -ENOMEM;
goto out;
if (ret == -BCH_ERR_option_needs_open_fs) {
ret = 0;
if (parse_later) {
prt_printf(parse_later, "%s=%s,", name, val);
if (parse_later->allocation_failure)
ret = -ENOMEM;
}
ret = 0;
goto out;
}
@ -567,28 +568,24 @@ int bch2_parse_one_mount_opt(struct bch_fs *c, struct bch_opts *opts,
bch2_opt_set_by_id(opts, id, v);
ret = 0;
goto out;
bad_opt:
pr_err("Bad mount option %s", name);
ret = -BCH_ERR_option_name;
goto out;
bad_val:
pr_err("Invalid mount option %s", err.buf);
ret = -BCH_ERR_option_value;
out:
printbuf_exit(&err);
return ret;
bad_opt:
ret = -BCH_ERR_option_name;
goto out;
bad_val:
ret = -BCH_ERR_option_value;
goto out;
}
int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
struct printbuf *parse_later, char *options)
struct printbuf *parse_later, char *options,
bool ignore_unknown)
{
char *copied_opts, *copied_opts_start;
char *opt, *name, *val;
int ret;
int ret = 0;
if (!options)
return 0;
@ -613,14 +610,14 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
val = opt;
ret = bch2_parse_one_mount_opt(c, opts, parse_later, name, val);
if (ret < 0)
goto out;
if (ret == -BCH_ERR_option_name && ignore_unknown)
ret = 0;
if (ret) {
pr_err("Error parsing option %s: %s", name, bch2_err_str(ret));
break;
}
}
ret = 0;
goto out;
out:
kfree(copied_opts_start);
return ret;
}

View File

@ -636,7 +636,7 @@ int bch2_opts_check_may_set(struct bch_fs *);
int bch2_parse_one_mount_opt(struct bch_fs *, struct bch_opts *,
struct printbuf *, const char *, const char *);
int bch2_parse_mount_opts(struct bch_fs *, struct bch_opts *, struct printbuf *,
char *);
char *, bool);
/* inode opts: */