diff options
Diffstat (limited to 'fs/incfs/main.c')
-rw-r--r-- | fs/incfs/main.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/fs/incfs/main.c b/fs/incfs/main.c new file mode 100644 index 000000000000..23cf3fefac97 --- /dev/null +++ b/fs/incfs/main.c | |||
@@ -0,0 +1,116 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright 2018 Google LLC | ||
4 | */ | ||
5 | #include <linux/fs.h> | ||
6 | #include <linux/init.h> | ||
7 | #include <linux/module.h> | ||
8 | |||
9 | #include <uapi/linux/incrementalfs.h> | ||
10 | |||
11 | #include "vfs.h" | ||
12 | |||
13 | #define INCFS_NODE_FEATURES "features" | ||
14 | |||
15 | static struct file_system_type incfs_fs_type = { | ||
16 | .owner = THIS_MODULE, | ||
17 | .name = INCFS_NAME, | ||
18 | .mount = incfs_mount_fs, | ||
19 | .kill_sb = incfs_kill_sb, | ||
20 | .fs_flags = 0 | ||
21 | }; | ||
22 | |||
23 | static struct kobject *sysfs_root, *featurefs_root; | ||
24 | |||
25 | static ssize_t supported(struct kobject *kobj, | ||
26 | struct kobj_attribute *attr, char *buff) | ||
27 | { | ||
28 | return snprintf(buff, PAGE_SIZE, "supported\n"); | ||
29 | } | ||
30 | |||
31 | typedef ssize_t (*const attr_show)(struct kobject *kobj, | ||
32 | struct kobj_attribute *attr, char *buff); | ||
33 | |||
34 | #define _DECLARE_FEATURE_FLAG(name) \ | ||
35 | static attr_show name##_show = supported; \ | ||
36 | static struct kobj_attribute name##_attr = __ATTR_RO(name) | ||
37 | |||
38 | #define DECLARE_FEATURE_FLAG(name) _DECLARE_FEATURE_FLAG(name) | ||
39 | |||
40 | DECLARE_FEATURE_FLAG(corefs); | ||
41 | DECLARE_FEATURE_FLAG(zstd); | ||
42 | DECLARE_FEATURE_FLAG(v2); | ||
43 | |||
44 | static struct attribute *attributes[] = { | ||
45 | &corefs_attr.attr, | ||
46 | &zstd_attr.attr, | ||
47 | &v2_attr.attr, | ||
48 | NULL, | ||
49 | }; | ||
50 | |||
51 | static const struct attribute_group attr_group = { | ||
52 | .attrs = attributes, | ||
53 | }; | ||
54 | |||
55 | static int __init init_sysfs(void) | ||
56 | { | ||
57 | int res = 0; | ||
58 | |||
59 | sysfs_root = kobject_create_and_add(INCFS_NAME, fs_kobj); | ||
60 | if (!sysfs_root) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | featurefs_root = kobject_create_and_add(INCFS_NODE_FEATURES, | ||
64 | sysfs_root); | ||
65 | if (!featurefs_root) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | res = sysfs_create_group(featurefs_root, &attr_group); | ||
69 | if (res) { | ||
70 | kobject_put(sysfs_root); | ||
71 | sysfs_root = NULL; | ||
72 | } | ||
73 | return res; | ||
74 | } | ||
75 | |||
76 | static void cleanup_sysfs(void) | ||
77 | { | ||
78 | if (featurefs_root) { | ||
79 | sysfs_remove_group(featurefs_root, &attr_group); | ||
80 | kobject_put(featurefs_root); | ||
81 | featurefs_root = NULL; | ||
82 | } | ||
83 | |||
84 | if (sysfs_root) { | ||
85 | kobject_put(sysfs_root); | ||
86 | sysfs_root = NULL; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static int __init init_incfs_module(void) | ||
91 | { | ||
92 | int err = 0; | ||
93 | |||
94 | err = init_sysfs(); | ||
95 | if (err) | ||
96 | return err; | ||
97 | |||
98 | err = register_filesystem(&incfs_fs_type); | ||
99 | if (err) | ||
100 | cleanup_sysfs(); | ||
101 | |||
102 | return err; | ||
103 | } | ||
104 | |||
105 | static void __exit cleanup_incfs_module(void) | ||
106 | { | ||
107 | cleanup_sysfs(); | ||
108 | unregister_filesystem(&incfs_fs_type); | ||
109 | } | ||
110 | |||
111 | module_init(init_incfs_module); | ||
112 | module_exit(cleanup_incfs_module); | ||
113 | |||
114 | MODULE_LICENSE("GPL v2"); | ||
115 | MODULE_AUTHOR("Eugene Zemtsov <ezemtsov@google.com>"); | ||
116 | MODULE_DESCRIPTION("Incremental File System"); | ||