[PATCH 2/2] cachefiles: support query cachefiles ondemand feature

Hongbo Li lihongbo22 at huawei.com
Fri Jun 21 16:18:08 AEST 2024


Erofs over fscache need CONFIG_CACHEFILES_ONDEMAND in cachefiles
module. We cannot know whether it is supported from userspace, so
we export this feature to user by sysfs interface.

[Before]
$ cat /sys/fs/cachefiles/features/cachefiles_ondemand
cat: /sys/fs/cachefiles/features/cachefiles_ondemand: No such file or directory

[After]
$ cat /sys/fs/cachefiles/features/cachefiles_ondemand
supported

Signed-off-by: Hongbo Li <lihongbo22 at huawei.com>
---
 fs/cachefiles/Makefile   |   3 +-
 fs/cachefiles/internal.h |   7 +++
 fs/cachefiles/main.c     |   7 +++
 fs/cachefiles/sysfs.c    | 101 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 fs/cachefiles/sysfs.c

diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
index c37a7a9af10b..e5d9dd27f94f 100644
--- a/fs/cachefiles/Makefile
+++ b/fs/cachefiles/Makefile
@@ -13,7 +13,8 @@ cachefiles-y := \
 	namei.o \
 	security.o \
 	volume.o \
-	xattr.o
+	xattr.o \
+	sysfs.o
 
 cachefiles-$(CONFIG_CACHEFILES_ERROR_INJECTION) += error_inject.o
 cachefiles-$(CONFIG_CACHEFILES_ONDEMAND) += ondemand.o
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 6845a90cdfcc..4926684b3044 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -419,6 +419,13 @@ extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie);
 extern bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume);
 extern int cachefiles_check_volume_xattr(struct cachefiles_volume *volume);
 
+/*
+ * sysfs.c
+ */
+
+int __init cachefiles_init_sysfs(void);
+void cachefiles_exit_sysfs(void);
+
 /*
  * Error handling
  */
diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
index 3f369c6f816d..0dcad6bb4b1f 100644
--- a/fs/cachefiles/main.c
+++ b/fs/cachefiles/main.c
@@ -64,9 +64,15 @@ static int __init cachefiles_init(void)
 		goto error_object_jar;
 	}
 
+	ret = cachefiles_init_sysfs();
+	if (ret)
+		goto sysfs_err;
+
 	pr_info("Loaded\n");
 	return 0;
 
+sysfs_err:
+	kmem_cache_destroy(cachefiles_object_jar);
 error_object_jar:
 	misc_deregister(&cachefiles_dev);
 error_dev:
@@ -85,6 +91,7 @@ static void __exit cachefiles_exit(void)
 {
 	pr_info("Unloading\n");
 
+	cachefiles_exit_sysfs();
 	kmem_cache_destroy(cachefiles_object_jar);
 	misc_deregister(&cachefiles_dev);
 	cachefiles_unregister_error_injection();
diff --git a/fs/cachefiles/sysfs.c b/fs/cachefiles/sysfs.c
new file mode 100644
index 000000000000..adfb260df59c
--- /dev/null
+++ b/fs/cachefiles/sysfs.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+
+#include "internal.h"
+
+enum {
+	attr_feature,
+};
+
+struct cachefiles_attr {
+	struct attribute attr;
+	short attr_id;
+};
+
+#define CACHEFILES_ATTR(_name, _mode, _id)				\
+static struct cachefiles_attr cachefiles_attr_##_name = {		\
+	.attr = {.name = __stringify(_name), .mode = _mode },		\
+	.attr_id = attr_##_id,						\
+}
+
+#define CACHEFILES_ATTR_FEATURE(_name) CACHEFILES_ATTR(_name, 0444, feature)
+
+#define ATTR_LIST(name) (&cachefiles_attr_##name.attr)
+
+/* supported features of cachefiles */
+#if IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND)
+CACHEFILES_ATTR_FEATURE(cachefiles_ondemand);
+#endif
+
+static struct attribute *cachefiles_feat_attrs[] = {
+#if IS_ENABLED(CONFIG_CACHEFILES_ONDEMAND)
+	ATTR_LIST(cachefiles_ondemand),
+	NULL,
+#endif
+};
+
+ATTRIBUTE_GROUPS(cachefiles_feat);
+
+static ssize_t cachefiles_attr_show(struct kobject *kobj,
+				struct attribute *attr, char *buf)
+{
+	struct cachefiles_attr *a = container_of(attr, struct cachefiles_attr, attr);
+
+	switch (a->attr_id) {
+	case attr_feature:
+		return sysfs_emit(buf, "supported\n");
+	}
+
+	return 0;
+};
+
+static const struct sysfs_ops cachefiles_attr_ops = {
+	.show = cachefiles_attr_show,
+};
+
+static const struct kobj_type cachefiles_ktype = {
+	.sysfs_ops	= &cachefiles_attr_ops,
+};
+
+static struct kset cachefiles_root = {
+	.kobj	= {.ktype = &cachefiles_ktype},
+};
+
+static const struct kobj_type cachefiles_feat_ktype = {
+	.default_groups = cachefiles_feat_groups,
+	.sysfs_ops	= &cachefiles_attr_ops,
+};
+
+static struct kobject cachefiles_feat = {
+	.kset	= &cachefiles_root,
+};
+
+int __init cachefiles_init_sysfs(void)
+{
+	int ret;
+
+	kobject_set_name(&cachefiles_root.kobj, "cachefiles");
+	cachefiles_root.kobj.parent = fs_kobj;
+	ret = kset_register(&cachefiles_root);
+	if (ret)
+		goto root_err;
+
+	ret = kobject_init_and_add(&cachefiles_feat, &cachefiles_feat_ktype,
+				   NULL, "features");
+	if (ret)
+		goto feat_err;
+	return ret;
+
+feat_err:
+	kobject_put(&cachefiles_feat);
+	kset_unregister(&cachefiles_root);
+root_err:
+	return ret;
+}
+
+void cachefiles_exit_sysfs(void)
+{
+	kobject_put(&cachefiles_feat);
+	kset_unregister(&cachefiles_root);
+}
-- 
2.34.1



More information about the Linux-erofs mailing list