1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /* Network filesystem caching backend to use cache files on a premounted
3   * filesystem
4   *
5   * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
6   * Written by David Howells (dhowells@redhat.com)
7   */
8  
9  #include <linux/module.h>
10  #include <linux/init.h>
11  #include <linux/sched.h>
12  #include <linux/completion.h>
13  #include <linux/slab.h>
14  #include <linux/fs.h>
15  #include <linux/file.h>
16  #include <linux/namei.h>
17  #include <linux/mount.h>
18  #include <linux/statfs.h>
19  #include <linux/sysctl.h>
20  #include <linux/miscdevice.h>
21  #include <linux/netfs.h>
22  #include <trace/events/netfs.h>
23  #define CREATE_TRACE_POINTS
24  #include "internal.h"
25  
26  unsigned cachefiles_debug;
27  module_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO);
28  MODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask");
29  
30  MODULE_DESCRIPTION("Mounted-filesystem based cache");
31  MODULE_AUTHOR("Red Hat, Inc.");
32  MODULE_LICENSE("GPL");
33  
34  struct kmem_cache *cachefiles_object_jar;
35  
36  static struct miscdevice cachefiles_dev = {
37  	.minor	= MISC_DYNAMIC_MINOR,
38  	.name	= "cachefiles",
39  	.fops	= &cachefiles_daemon_fops,
40  };
41  
42  /*
43   * initialise the fs caching module
44   */
cachefiles_init(void)45  static int __init cachefiles_init(void)
46  {
47  	int ret;
48  
49  	ret = cachefiles_register_error_injection();
50  	if (ret < 0)
51  		goto error_einj;
52  	ret = misc_register(&cachefiles_dev);
53  	if (ret < 0)
54  		goto error_dev;
55  
56  	/* create an object jar */
57  	ret = -ENOMEM;
58  	cachefiles_object_jar =
59  		kmem_cache_create("cachefiles_object_jar",
60  				  sizeof(struct cachefiles_object),
61  				  0, SLAB_HWCACHE_ALIGN, NULL);
62  	if (!cachefiles_object_jar) {
63  		pr_notice("Failed to allocate an object jar\n");
64  		goto error_object_jar;
65  	}
66  
67  	pr_info("Loaded\n");
68  	return 0;
69  
70  error_object_jar:
71  	misc_deregister(&cachefiles_dev);
72  error_dev:
73  	cachefiles_unregister_error_injection();
74  error_einj:
75  	pr_err("failed to register: %d\n", ret);
76  	return ret;
77  }
78  
79  fs_initcall(cachefiles_init);
80  
81  /*
82   * clean up on module removal
83   */
cachefiles_exit(void)84  static void __exit cachefiles_exit(void)
85  {
86  	pr_info("Unloading\n");
87  
88  	kmem_cache_destroy(cachefiles_object_jar);
89  	misc_deregister(&cachefiles_dev);
90  	cachefiles_unregister_error_injection();
91  }
92  
93  module_exit(cachefiles_exit);
94