History log of /linux-master/include/linux/fs_parser.h
Revision Date Author Comments
# e3ea75ee 04-Oct-2022 Lukas Czerner <lczerner@redhat.com>

ext4: journal_path mount options should follow links

Before the commit 461c3af045d3 ("ext4: Change handle_mount_opt() to use
fs_parameter") ext4 mount option journal_path did follow links in the
provided path.

Bring this behavior back by allowing to pass pathwalk flags to
fs_lookup_param().

Fixes: 461c3af045d3 ("ext4: Change handle_mount_opt() to use fs_parameter")
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20221004135803.32283-1-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org


# 6abfaaf1 27-Oct-2021 Lukas Czerner <lczerner@redhat.com>

fs_parse: allow parameter value to be empty

Allow parameter value to be empty by specifying fs_param_can_be_empty
flag.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Link: https://lore.kernel.org/r/20211027141857.33657-2-lczerner@redhat.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>


# ffbc3dd1 16-Sep-2020 Alexey Dobriyan <adobriyan@gmail.com>

fs: fix cast in fsparam_u32hex() macro

Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 328de528 17-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

turn fs_param_is_... into functions

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 48ce73b1 17-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

fs_parse: handle optional arguments sanely

Don't bother with "mixed" options that would allow both the
form with and without argument (i.e. both -o foo and -o foo=bar).
Rather than trying to shove both into a single fs_parameter_spec,
allow having with-argument and no-argument specs with the same
name and teach fs_parse to handle that.

There are very few options of that sort, and they are actually
easier to handle that way - callers end up with less postprocessing.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# d7167b14 07-Sep-2019 Al Viro <viro@zeniv.linux.org.uk>

fs_parse: fold fs_parameter_desc/fs_parameter_spec

The former contains nothing but a pointer to an array of the latter...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 96cafb9c 06-Dec-2019 Eric Sandeen <sandeen@sandeen.net>

fs_parser: remove fs_parameter_description name field

Unused now.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# cc3c0b53 20-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

add prefix to fs_context->log

... turning it into struct p_log embedded into fs_context. Initialize
the prefix with fs_type->name, turning fs_parse() into a trivial
inline wrapper for __fs_parse().

This makes fs_parameter_description->name completely unused.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 7f5d3814 20-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

new primitive: __fs_parse()

fs_parse() analogue taking p_log instead of fs_context.
fs_parse() turned into a wrapper, callers in ceph_common and rbd
switched to __fs_parse().

As the result, fs_parse() never gets NULL fs_context and neither
do fs_context-based logging primitives

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 34264ae3 16-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

don't bother with explicit length argument for __lookup_constant()

Have the arrays of constant_table self-terminated (by NULL ->name
in the final entry). Simplifies lookup_constant() and allows to
reuse the search for enum params as well.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 5eede625 16-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

fold struct fs_parameter_enum into struct constant_table

no real difference now

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 2710c957a 06-Sep-2019 Al Viro <viro@zeniv.linux.org.uk>

fs_parse: get rid of ->enums

Don't do a single array; attach them to fsparam_enum() entry
instead. And don't bother trying to embed the names into those -
it actually loses memory, with no real speedup worth mentioning.

Simplifies validation as well.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# 0f89589a 17-Dec-2019 Al Viro <viro@zeniv.linux.org.uk>

Pass consistent param->type to fs_parse()

As it is, vfs_parse_fs_string() makes "foo" and "foo=" indistinguishable;
both get fs_value_is_string for ->type and NULL for ->string. To make
it even more unpleasant, that combination is impossible to produce with
fsconfig().

Much saner rules would be
"foo" => fs_value_is_flag, NULL
"foo=" => fs_value_is_string, ""
"foo=bar" => fs_value_is_string, "bar"
All cases are distinguishable, all results are expressable by fsconfig(),
->has_value checks are much simpler that way (to the point of the field
being useless) and quite a few regressions go away (gfs2 has no business
accepting -o nodebug=, for example).

Partially based upon patches from Miklos.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>


# b4d0d230 20-May-2019 Thomas Gleixner <tglx@linutronix.de>

treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 36

Based on 1 normalized pattern(s):

this program is free software you can redistribute it and or modify
it under the terms of the gnu general public licence as published by
the free software foundation either version 2 of the licence or at
your option any later version

extracted by the scancode license scanner the SPDX license identifier

GPL-2.0-or-later

has been chosen to replace the boilerplate/reference in 114 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Allison Randal <allison@lohutok.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190520170857.552531963@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>


# 31d921c7 01-Nov-2018 David Howells <dhowells@redhat.com>

vfs: Add configuration parser helpers

Because the new API passes in key,value parameters, match_token() cannot be
used with it. Instead, provide three new helpers to aid with parsing:

(1) fs_parse(). This takes a parameter and a simple static description of
all the parameters and maps the key name to an ID. It returns 1 on a
match, 0 on no match if unknowns should be ignored and some other
negative error code on a parse error.

The parameter description includes a list of key names to IDs, desired
parameter types and a list of enumeration name -> ID mappings.

[!] Note that for the moment I've required that the key->ID mapping
array is expected to be sorted and unterminated. The size of the
array is noted in the fsconfig_parser struct. This allows me to use
bsearch(), but I'm not sure any performance gain is worth the hassle
of requiring people to keep the array sorted.

The parameter type array is sized according to the number of parameter
IDs and is indexed directly. The optional enum mapping array is an
unterminated, unsorted list and the size goes into the fsconfig_parser
struct.

The function can do some additional things:

(a) If it's not ambiguous and no value is given, the prefix "no" on
a key name is permitted to indicate that the parameter should
be considered negatory.

(b) If the desired type is a single simple integer, it will perform
an appropriate conversion and store the result in a union in
the parse result.

(c) If the desired type is an enumeration, {key ID, name} will be
looked up in the enumeration list and the matching value will
be stored in the parse result union.

(d) Optionally generate an error if the key is unrecognised.

This is called something like:

enum rdt_param {
Opt_cdp,
Opt_cdpl2,
Opt_mba_mpbs,
nr__rdt_params
};

const struct fs_parameter_spec rdt_param_specs[nr__rdt_params] = {
[Opt_cdp] = { fs_param_is_bool },
[Opt_cdpl2] = { fs_param_is_bool },
[Opt_mba_mpbs] = { fs_param_is_bool },
};

const const char *const rdt_param_keys[nr__rdt_params] = {
[Opt_cdp] = "cdp",
[Opt_cdpl2] = "cdpl2",
[Opt_mba_mpbs] = "mba_mbps",
};

const struct fs_parameter_description rdt_parser = {
.name = "rdt",
.nr_params = nr__rdt_params,
.keys = rdt_param_keys,
.specs = rdt_param_specs,
.no_source = true,
};

int rdt_parse_param(struct fs_context *fc,
struct fs_parameter *param)
{
struct fs_parse_result parse;
struct rdt_fs_context *ctx = rdt_fc2context(fc);
int ret;

ret = fs_parse(fc, &rdt_parser, param, &parse);
if (ret < 0)
return ret;

switch (parse.key) {
case Opt_cdp:
ctx->enable_cdpl3 = true;
return 0;
case Opt_cdpl2:
ctx->enable_cdpl2 = true;
return 0;
case Opt_mba_mpbs:
ctx->enable_mba_mbps = true;
return 0;
}

return -EINVAL;
}

(2) fs_lookup_param(). This takes a { dirfd, path, LOOKUP_EMPTY? } or
string value and performs an appropriate path lookup to convert it
into a path object, which it will then return.

If the desired type was a blockdev, the type of the looked up inode
will be checked to make sure it is one.

This can be used like:

enum foo_param {
Opt_source,
nr__foo_params
};

const struct fs_parameter_spec foo_param_specs[nr__foo_params] = {
[Opt_source] = { fs_param_is_blockdev },
};

const char *char foo_param_keys[nr__foo_params] = {
[Opt_source] = "source",
};

const struct constant_table foo_param_alt_keys[] = {
{ "device", Opt_source },
};

const struct fs_parameter_description foo_parser = {
.name = "foo",
.nr_params = nr__foo_params,
.nr_alt_keys = ARRAY_SIZE(foo_param_alt_keys),
.keys = foo_param_keys,
.alt_keys = foo_param_alt_keys,
.specs = foo_param_specs,
};

int foo_parse_param(struct fs_context *fc,
struct fs_parameter *param)
{
struct fs_parse_result parse;
struct foo_fs_context *ctx = foo_fc2context(fc);
int ret;

ret = fs_parse(fc, &foo_parser, param, &parse);
if (ret < 0)
return ret;

switch (parse.key) {
case Opt_source:
return fs_lookup_param(fc, &foo_parser, param,
&parse, &ctx->source);
default:
return -EINVAL;
}
}

(3) lookup_constant(). This takes a table of named constants and looks up
the given name within it. The table is expected to be sorted such
that bsearch() be used upon it.

Possibly I should require the table be terminated and just use a
for-loop to scan it instead of using bsearch() to reduce hassle.

Tables look something like:

static const struct constant_table bool_names[] = {
{ "0", false },
{ "1", true },
{ "false", false },
{ "no", false },
{ "true", true },
{ "yes", true },
};

and a lookup is done with something like:

b = lookup_constant(bool_names, param->string, -1);

Additionally, optional validation routines for the parameter description
are provided that can be enabled at compile time. A later patch will
invoke these when a filesystem is registered.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>