Implements the bare minimum functionality to safely mount and unmount the sample_kernfs filesystem. Signed-off-by: David Reaver <me@xxxxxxxxxxxxxxx> --- samples/kernfs/sample_kernfs.c | 69 +++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/samples/kernfs/sample_kernfs.c b/samples/kernfs/sample_kernfs.c index 82d4b73a4534..3ea8411a72ae 100644 --- a/samples/kernfs/sample_kernfs.c +++ b/samples/kernfs/sample_kernfs.c @@ -6,12 +6,79 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ +#include <linux/fs.h> +#include <linux/fs_context.h> +#include <linux/kernfs.h> #include <linux/kernel.h> #include <linux/module.h> +#define SAMPLE_KERNFS_MAGIC 0x8d000ff0 + +static void sample_kernfs_fs_context_free(struct fs_context *fc) +{ + struct kernfs_fs_context *kfc = fc->fs_private; + + kernfs_free_fs_context(fc); + kfree(kfc); +} + +static const struct fs_context_operations sample_kernfs_fs_context_ops = { + .get_tree = kernfs_get_tree, + .free = sample_kernfs_fs_context_free, +}; + +static int sample_kernfs_init_fs_context(struct fs_context *fc) +{ + struct kernfs_fs_context *kfc; + struct kernfs_root *root; + int err; + + kfc = kzalloc(sizeof(struct kernfs_fs_context), GFP_KERNEL); + if (!kfc) + return -ENOMEM; + + root = kernfs_create_root(NULL, 0, NULL); + if (IS_ERR(root)) { + err = PTR_ERR(root); + goto err_free_kfc; + } + + kfc->root = root; + kfc->magic = SAMPLE_KERNFS_MAGIC; + fc->fs_private = kfc; + fc->ops = &sample_kernfs_fs_context_ops; + fc->global = true; + + return 0; + +err_free_kfc: + kfree(kfc); + return err; +} + +static void sample_kernfs_kill_sb(struct super_block *sb) +{ + struct kernfs_root *root = kernfs_root_from_sb(sb); + + kernfs_kill_sb(sb); + kernfs_destroy_root(root); +} + +static struct file_system_type sample_kernfs_fs_type = { + .name = "sample_kernfs", + .init_fs_context = sample_kernfs_init_fs_context, + .kill_sb = sample_kernfs_kill_sb, + .fs_flags = FS_USERNS_MOUNT, +}; + static int __init sample_kernfs_init(void) { - pr_info("Loaded sample_kernfs module.\n"); + int err; + + err = register_filesystem(&sample_kernfs_fs_type); + if (err) + return err; + return 0; }