mm/shmem: refactor to reuse vfs_parse_monolithic_sep for option parsing

shmem_parse_options() is refactored to use vfs_parse_monolithic_sep() with
a custom separator function, shmem_next_opt().  This eliminates redundant
logic for parsing comma-separated options and ensures consistency with
other kernel code that uses the same interface.

The vfs_parse_monolithic_sep() helper was introduced in commit
e001d1447cd4 ("fs: factor out vfs_parse_monolithic_sep() helper").

Link: https://lkml.kernel.org/r/20241205094521.1244678-1-guoweikang.kernel@gmail.com
Signed-off-by: Guo Weikang <guoweikang.kernel@gmail.com>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Guo Weikang 2024-12-05 17:45:21 +08:00 committed by Andrew Morton
parent ea8c2ac2b3
commit 53d93d2915

View File

@ -4646,48 +4646,37 @@ bad_value:
return invalfc(fc, "Bad value for '%s'", param->key);
}
static int shmem_parse_options(struct fs_context *fc, void *data)
static char *shmem_next_opt(char **s)
{
char *options = data;
char *sbegin = *s;
char *p;
if (options) {
int err = security_sb_eat_lsm_opts(options, &fc->security);
if (err)
return err;
}
if (sbegin == NULL)
return NULL;
while (options != NULL) {
char *this_char = options;
for (;;) {
/*
* NUL-terminate this option: unfortunately,
* mount options form a comma-separated list,
* but mpol's nodelist may also contain commas.
*/
options = strchr(options, ',');
if (options == NULL)
break;
options++;
if (!isdigit(*options)) {
options[-1] = '\0';
break;
}
}
if (*this_char) {
char *value = strchr(this_char, '=');
size_t len = 0;
int err;
if (value) {
*value++ = '\0';
len = strlen(value);
}
err = vfs_parse_fs_string(fc, this_char, value, len);
if (err < 0)
return err;
/*
* NUL-terminate this option: unfortunately,
* mount options form a comma-separated list,
* but mpol's nodelist may also contain commas.
*/
for (;;) {
p = strchr(*s, ',');
if (p == NULL)
break;
*s = p + 1;
if (!isdigit(*(p+1))) {
*p = '\0';
return sbegin;
}
}
return 0;
*s = NULL;
return sbegin;
}
static int shmem_parse_monolithic(struct fs_context *fc, void *data)
{
return vfs_parse_monolithic_sep(fc, data, shmem_next_opt);
}
/*
@ -5037,7 +5026,7 @@ static const struct fs_context_operations shmem_fs_context_ops = {
.free = shmem_free_fc,
.get_tree = shmem_get_tree,
#ifdef CONFIG_TMPFS
.parse_monolithic = shmem_parse_options,
.parse_monolithic = shmem_parse_monolithic,
.parse_param = shmem_parse_one,
.reconfigure = shmem_reconfigure,
#endif