This function will be used by MUSE too, let's share it. Signed-off-by: Richard Weinberger <richard@xxxxxx> --- fs/fuse/Kconfig | 4 +++ fs/fuse/Makefile | 1 + fs/fuse/cuse.c | 58 +-------------------------------------- fs/fuse/fuse_i.h | 2 ++ fs/fuse/helper.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 57 deletions(-) create mode 100644 fs/fuse/helper.c diff --git a/fs/fuse/Kconfig b/fs/fuse/Kconfig index 40ce9a1c12e5..9c8cc1e7b3a5 100644 --- a/fs/fuse/Kconfig +++ b/fs/fuse/Kconfig @@ -18,9 +18,13 @@ config FUSE_FS If you want to develop a userspace FS, or if you want to use a filesystem based on FUSE, answer Y or M. +config FUSE_HELPER + def_bool n + config CUSE tristate "Character device in Userspace support" depends on FUSE_FS + select FUSE_HELPER help This FUSE extension allows character devices to be implemented in userspace. diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index 8c7021fb2cd4..7a5768cce6be 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -9,5 +9,6 @@ obj-$(CONFIG_VIRTIO_FS) += virtiofs.o fuse-y := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o fuse-$(CONFIG_FUSE_DAX) += dax.o +fuse-$(CONFIG_FUSE_HELPER) += helper.o virtiofs-y := virtio_fs.o diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 45082269e698..fe8515844064 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -199,62 +199,6 @@ struct cuse_devinfo { const char *name; }; -/** - * cuse_parse_one - parse one key=value pair - * @pp: i/o parameter for the current position - * @end: points to one past the end of the packed string - * @keyp: out parameter for key - * @valp: out parameter for value - * - * *@pp points to packed strings - "key0=val0\0key1=val1\0" which ends - * at @end - 1. This function parses one pair and set *@keyp to the - * start of the key and *@valp to the start of the value. Note that - * the original string is modified such that the key string is - * terminated with '\0'. *@pp is updated to point to the next string. - * - * RETURNS: - * 1 on successful parse, 0 on EOF, -errno on failure. - */ -static int cuse_parse_one(char **pp, char *end, char **keyp, char **valp) -{ - char *p = *pp; - char *key, *val; - - while (p < end && *p == '\0') - p++; - if (p == end) - return 0; - - if (end[-1] != '\0') { - pr_err("info not properly terminated\n"); - return -EINVAL; - } - - key = val = p; - p += strlen(p); - - if (valp) { - strsep(&val, "="); - if (!val) - val = key + strlen(key); - key = strstrip(key); - val = strstrip(val); - } else - key = strstrip(key); - - if (!strlen(key)) { - pr_err("zero length info key specified\n"); - return -EINVAL; - } - - *pp = p; - *keyp = key; - if (valp) - *valp = val; - - return 1; -} - /** * cuse_parse_dev_info - parse device info * @p: device info string @@ -275,7 +219,7 @@ static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo) int rc; while (true) { - rc = cuse_parse_one(&p, end, &key, &val); + rc = fuse_kv_parse_one(&p, end, &key, &val); if (rc < 0) return rc; if (!rc) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d23954908610..8eba93cd8fb8 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1225,5 +1225,7 @@ void fuse_dax_cancel_work(struct fuse_conn *fc); /* file.c */ struct page **fuse_pages_alloc(unsigned int npages, gfp_t flags, struct fuse_page_desc **desc); +/* helper.c */ +int fuse_kv_parse_one(char **pp, char *end, char **keyp, char **valp); #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/helper.c b/fs/fuse/helper.c new file mode 100644 index 000000000000..0c828daf8e8a --- /dev/null +++ b/fs/fuse/helper.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Helper functions used by CUSE and MUSE + * + * Copyright (C) 2008-2009 SUSE Linux Products GmbH + * Copyright (C) 2008-2009 Tejun Heo <tj@xxxxxxxxxx> + * + */ + +#include <linux/string.h> +#include <linux/module.h> + +#include "fuse_i.h" + +/** + * fuse_kv_parse_one - parse one key=value pair + * @pp: i/o parameter for the current position + * @end: points to one past the end of the packed string + * @keyp: out parameter for key + * @valp: out parameter for value + * + * *@pp points to packed strings - "key0=val0\0key1=val1\0" which ends + * at @end - 1. This function parses one pair and set *@keyp to the + * start of the key and *@valp to the start of the value. Note that + * the original string is modified such that the key string is + * terminated with '\0'. *@pp is updated to point to the next string. + * + * RETURNS: + * 1 on successful parse, 0 on EOF, -errno on failure. + */ +int fuse_kv_parse_one(char **pp, char *end, char **keyp, char **valp) +{ + char *p = *pp; + char *key, *val; + + while (p < end && *p == '\0') + p++; + if (p == end) + return 0; + + if (end[-1] != '\0') { + pr_err("info not properly terminated\n"); + return -EINVAL; + } + + key = val = p; + p += strlen(p); + + if (valp) { + strsep(&val, "="); + if (!val) + val = key + strlen(key); + key = strstrip(key); + val = strstrip(val); + } else + key = strstrip(key); + + if (!strlen(key)) { + pr_err("zero length info key specified\n"); + return -EINVAL; + } + + *pp = p; + *keyp = key; + if (valp) + *valp = val; + + return 1; +} +EXPORT_SYMBOL_GPL(fuse_kv_parse_one); -- 2.26.2