Commit a474d843 authored by Guo Weikang's avatar Guo Weikang Committed by Andrew Morton
Browse files

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
e001d144 ("fs: factor out vfs_parse_monolithic_sep() helper").

Link: https://lkml.kernel.org/r/20241205094521.1244678-1-guoweikang.kernel@gmail.com


Signed-off-by: default avatarGuo Weikang <guoweikang.kernel@gmail.com>
Cc: Amir Goldstein <amir73il@gmail.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 19b65ffa
Loading
Loading
Loading
Loading
+27 −38
Original line number Diff line number Diff line
@@ -4647,48 +4647,37 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
	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';
	for (;;) {
		p = strchr(*s, ',');
		if (p == NULL)
			break;
		*s = p + 1;
		if (!isdigit(*(p+1))) {
			*p = '\0';
			return sbegin;
		}
	}
		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;
		}
	*s = NULL;
	return sbegin;
}
	return 0;

static int shmem_parse_monolithic(struct fs_context *fc, void *data)
{
	return vfs_parse_monolithic_sep(fc, data, shmem_next_opt);
}

/*
@@ -5038,7 +5027,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