[PATCH 3/8] fuse: Make cuse_parse_one a common helper

Richard Weinberger
2021-01-24T23:22:21Z

This function will be used by MUSE too, let's share it.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
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 8c56a3fd2c4e..555856b0d998 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -1228,5 +1228,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@kernel.org>
+ *
+ */
+
+#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