177443f61SDavid Howells // SPDX-License-Identifier: GPL-2.0-or-later
277443f61SDavid Howells /* Network filesystem caching backend to use cache files on a premounted
377443f61SDavid Howells * filesystem
477443f61SDavid Howells *
577443f61SDavid Howells * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
677443f61SDavid Howells * Written by David Howells (dhowells@redhat.com)
777443f61SDavid Howells */
877443f61SDavid Howells
977443f61SDavid Howells #include <linux/module.h>
1077443f61SDavid Howells #include <linux/init.h>
1177443f61SDavid Howells #include <linux/sched.h>
1277443f61SDavid Howells #include <linux/completion.h>
1377443f61SDavid Howells #include <linux/slab.h>
1477443f61SDavid Howells #include <linux/fs.h>
1577443f61SDavid Howells #include <linux/file.h>
1677443f61SDavid Howells #include <linux/namei.h>
1777443f61SDavid Howells #include <linux/mount.h>
1877443f61SDavid Howells #include <linux/statfs.h>
1977443f61SDavid Howells #include <linux/sysctl.h>
2077443f61SDavid Howells #include <linux/miscdevice.h>
2177443f61SDavid Howells #include <linux/netfs.h>
2277443f61SDavid Howells #include <trace/events/netfs.h>
2377443f61SDavid Howells #define CREATE_TRACE_POINTS
2477443f61SDavid Howells #include "internal.h"
2577443f61SDavid Howells
2677443f61SDavid Howells unsigned cachefiles_debug;
2777443f61SDavid Howells module_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO);
2877443f61SDavid Howells MODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask");
2977443f61SDavid Howells
3077443f61SDavid Howells MODULE_DESCRIPTION("Mounted-filesystem based cache");
3177443f61SDavid Howells MODULE_AUTHOR("Red Hat, Inc.");
3277443f61SDavid Howells MODULE_LICENSE("GPL");
3377443f61SDavid Howells
34*df98e87fSDavid Howells struct kmem_cache *cachefiles_object_jar;
35*df98e87fSDavid Howells
368667d434SDavid Howells static struct miscdevice cachefiles_dev = {
378667d434SDavid Howells .minor = MISC_DYNAMIC_MINOR,
388667d434SDavid Howells .name = "cachefiles",
398667d434SDavid Howells .fops = &cachefiles_daemon_fops,
408667d434SDavid Howells };
418667d434SDavid Howells
4277443f61SDavid Howells /*
4377443f61SDavid Howells * initialise the fs caching module
4477443f61SDavid Howells */
cachefiles_init(void)4577443f61SDavid Howells static int __init cachefiles_init(void)
4677443f61SDavid Howells {
47a70f6526SDavid Howells int ret;
48a70f6526SDavid Howells
49a70f6526SDavid Howells ret = cachefiles_register_error_injection();
50a70f6526SDavid Howells if (ret < 0)
51a70f6526SDavid Howells goto error_einj;
528667d434SDavid Howells ret = misc_register(&cachefiles_dev);
538667d434SDavid Howells if (ret < 0)
548667d434SDavid Howells goto error_dev;
55a70f6526SDavid Howells
56*df98e87fSDavid Howells /* create an object jar */
57*df98e87fSDavid Howells ret = -ENOMEM;
58*df98e87fSDavid Howells cachefiles_object_jar =
59*df98e87fSDavid Howells kmem_cache_create("cachefiles_object_jar",
60*df98e87fSDavid Howells sizeof(struct cachefiles_object),
61*df98e87fSDavid Howells 0, SLAB_HWCACHE_ALIGN, NULL);
62*df98e87fSDavid Howells if (!cachefiles_object_jar) {
63*df98e87fSDavid Howells pr_notice("Failed to allocate an object jar\n");
64*df98e87fSDavid Howells goto error_object_jar;
65*df98e87fSDavid Howells }
66*df98e87fSDavid Howells
6777443f61SDavid Howells pr_info("Loaded\n");
6877443f61SDavid Howells return 0;
69a70f6526SDavid Howells
70*df98e87fSDavid Howells error_object_jar:
71*df98e87fSDavid Howells misc_deregister(&cachefiles_dev);
728667d434SDavid Howells error_dev:
738667d434SDavid Howells cachefiles_unregister_error_injection();
74a70f6526SDavid Howells error_einj:
75a70f6526SDavid Howells pr_err("failed to register: %d\n", ret);
76a70f6526SDavid Howells return ret;
7777443f61SDavid Howells }
7877443f61SDavid Howells
7977443f61SDavid Howells fs_initcall(cachefiles_init);
8077443f61SDavid Howells
8177443f61SDavid Howells /*
8277443f61SDavid Howells * clean up on module removal
8377443f61SDavid Howells */
cachefiles_exit(void)8477443f61SDavid Howells static void __exit cachefiles_exit(void)
8577443f61SDavid Howells {
8677443f61SDavid Howells pr_info("Unloading\n");
87a70f6526SDavid Howells
88*df98e87fSDavid Howells kmem_cache_destroy(cachefiles_object_jar);
898667d434SDavid Howells misc_deregister(&cachefiles_dev);
90a70f6526SDavid Howells cachefiles_unregister_error_injection();
9177443f61SDavid Howells }
9277443f61SDavid Howells
9377443f61SDavid Howells module_exit(cachefiles_exit);
94