18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* Network filesystem caching backend to use cache files on a premounted 38c2ecf20Sopenharmony_ci * filesystem 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 68c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/init.h> 118c2ecf20Sopenharmony_ci#include <linux/sched.h> 128c2ecf20Sopenharmony_ci#include <linux/completion.h> 138c2ecf20Sopenharmony_ci#include <linux/slab.h> 148c2ecf20Sopenharmony_ci#include <linux/fs.h> 158c2ecf20Sopenharmony_ci#include <linux/file.h> 168c2ecf20Sopenharmony_ci#include <linux/namei.h> 178c2ecf20Sopenharmony_ci#include <linux/mount.h> 188c2ecf20Sopenharmony_ci#include <linux/statfs.h> 198c2ecf20Sopenharmony_ci#include <linux/sysctl.h> 208c2ecf20Sopenharmony_ci#include <linux/miscdevice.h> 218c2ecf20Sopenharmony_ci#define CREATE_TRACE_POINTS 228c2ecf20Sopenharmony_ci#include "internal.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciunsigned cachefiles_debug; 258c2ecf20Sopenharmony_cimodule_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO); 268c2ecf20Sopenharmony_ciMODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask"); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Mounted-filesystem based cache"); 298c2ecf20Sopenharmony_ciMODULE_AUTHOR("Red Hat, Inc."); 308c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistruct kmem_cache *cachefiles_object_jar; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_cistatic struct miscdevice cachefiles_dev = { 358c2ecf20Sopenharmony_ci .minor = MISC_DYNAMIC_MINOR, 368c2ecf20Sopenharmony_ci .name = "cachefiles", 378c2ecf20Sopenharmony_ci .fops = &cachefiles_daemon_fops, 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic void cachefiles_object_init_once(void *_object) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci struct cachefiles_object *object = _object; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci memset(object, 0, sizeof(*object)); 458c2ecf20Sopenharmony_ci spin_lock_init(&object->work_lock); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * initialise the fs caching module 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_cistatic int __init cachefiles_init(void) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci int ret; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci ret = misc_register(&cachefiles_dev); 568c2ecf20Sopenharmony_ci if (ret < 0) 578c2ecf20Sopenharmony_ci goto error_dev; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* create an object jar */ 608c2ecf20Sopenharmony_ci ret = -ENOMEM; 618c2ecf20Sopenharmony_ci cachefiles_object_jar = 628c2ecf20Sopenharmony_ci kmem_cache_create("cachefiles_object_jar", 638c2ecf20Sopenharmony_ci sizeof(struct cachefiles_object), 648c2ecf20Sopenharmony_ci 0, 658c2ecf20Sopenharmony_ci SLAB_HWCACHE_ALIGN, 668c2ecf20Sopenharmony_ci cachefiles_object_init_once); 678c2ecf20Sopenharmony_ci if (!cachefiles_object_jar) { 688c2ecf20Sopenharmony_ci pr_notice("Failed to allocate an object jar\n"); 698c2ecf20Sopenharmony_ci goto error_object_jar; 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ret = cachefiles_proc_init(); 738c2ecf20Sopenharmony_ci if (ret < 0) 748c2ecf20Sopenharmony_ci goto error_proc; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci pr_info("Loaded\n"); 778c2ecf20Sopenharmony_ci return 0; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cierror_proc: 808c2ecf20Sopenharmony_ci kmem_cache_destroy(cachefiles_object_jar); 818c2ecf20Sopenharmony_cierror_object_jar: 828c2ecf20Sopenharmony_ci misc_deregister(&cachefiles_dev); 838c2ecf20Sopenharmony_cierror_dev: 848c2ecf20Sopenharmony_ci pr_err("failed to register: %d\n", ret); 858c2ecf20Sopenharmony_ci return ret; 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cifs_initcall(cachefiles_init); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* 918c2ecf20Sopenharmony_ci * clean up on module removal 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_cistatic void __exit cachefiles_exit(void) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci pr_info("Unloading\n"); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci cachefiles_proc_cleanup(); 988c2ecf20Sopenharmony_ci kmem_cache_destroy(cachefiles_object_jar); 998c2ecf20Sopenharmony_ci misc_deregister(&cachefiles_dev); 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cimodule_exit(cachefiles_exit); 103