1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* FS-Cache interface to CacheFiles 3 * 4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells ([email protected]) 6 */ 7 8 #include <linux/slab.h> 9 #include <linux/mount.h> 10 #include <linux/xattr.h> 11 #include <linux/file.h> 12 #include <linux/falloc.h> 13 #include <trace/events/fscache.h> 14 #include "internal.h" 15 16 static atomic_t cachefiles_object_debug_id; 17 18 /* 19 * Allocate a cache object record. 20 */ 21 static 22 struct cachefiles_object *cachefiles_alloc_object(struct fscache_cookie *cookie) 23 { 24 struct fscache_volume *vcookie = cookie->volume; 25 struct cachefiles_volume *volume = vcookie->cache_priv; 26 struct cachefiles_object *object; 27 28 _enter("{%s},%x,", vcookie->key, cookie->debug_id); 29 30 object = kmem_cache_zalloc(cachefiles_object_jar, GFP_KERNEL); 31 if (!object) 32 return NULL; 33 34 refcount_set(&object->ref, 1); 35 36 spin_lock_init(&object->lock); 37 INIT_LIST_HEAD(&object->cache_link); 38 object->volume = volume; 39 object->debug_id = atomic_inc_return(&cachefiles_object_debug_id); 40 object->cookie = fscache_get_cookie(cookie, fscache_cookie_get_attach_object); 41 42 fscache_count_object(vcookie->cache); 43 trace_cachefiles_ref(object->debug_id, cookie->debug_id, 1, 44 cachefiles_obj_new); 45 return object; 46 } 47 48 /* 49 * Note that an object has been seen. 50 */ 51 void cachefiles_see_object(struct cachefiles_object *object, 52 enum cachefiles_obj_ref_trace why) 53 { 54 trace_cachefiles_ref(object->debug_id, object->cookie->debug_id, 55 refcount_read(&object->ref), why); 56 } 57 58 /* 59 * Increment the usage count on an object; 60 */ 61 struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object, 62 enum cachefiles_obj_ref_trace why) 63 { 64 int r; 65 66 __refcount_inc(&object->ref, &r); 67 trace_cachefiles_ref(object->debug_id, object->cookie->debug_id, r, why); 68 return object; 69 } 70 71 /* 72 * dispose of a reference to an object 73 */ 74 void cachefiles_put_object(struct cachefiles_object *object, 75 enum cachefiles_obj_ref_trace why) 76 { 77 unsigned int object_debug_id = object->debug_id; 78 unsigned int cookie_debug_id = object->cookie->debug_id; 79 struct fscache_cache *cache; 80 bool done; 81 int r; 82 83 done = __refcount_dec_and_test(&object->ref, &r); 84 trace_cachefiles_ref(object_debug_id, cookie_debug_id, r, why); 85 if (done) { 86 _debug("- kill object OBJ%x", object_debug_id); 87 88 ASSERTCMP(object->file, ==, NULL); 89 90 kfree(object->d_name); 91 92 cache = object->volume->cache->cache; 93 fscache_put_cookie(object->cookie, fscache_cookie_put_object); 94 object->cookie = NULL; 95 kmem_cache_free(cachefiles_object_jar, object); 96 fscache_uncount_object(cache); 97 } 98 99 _leave(""); 100 } 101 102 const struct fscache_cache_ops cachefiles_cache_ops = { 103 .name = "cachefiles", 104 .acquire_volume = cachefiles_acquire_volume, 105 .free_volume = cachefiles_free_volume, 106 }; 107