1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* Internal definitions for FS-Cache 3 * 4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8 #ifdef pr_fmt 9 #undef pr_fmt 10 #endif 11 12 #define pr_fmt(fmt) "FS-Cache: " fmt 13 14 #include <linux/slab.h> 15 #include <linux/fscache-cache.h> 16 #include <trace/events/fscache.h> 17 #include <linux/sched.h> 18 #include <linux/seq_file.h> 19 20 /* 21 * cache.c 22 */ 23 #ifdef CONFIG_PROC_FS 24 extern const struct seq_operations fscache_caches_seq_ops; 25 #endif 26 bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why); 27 void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why); 28 struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache); 29 void fscache_put_cache(struct fscache_cache *cache, enum fscache_cache_trace where); 30 31 static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache) 32 { 33 return smp_load_acquire(&cache->state); 34 } 35 36 static inline bool fscache_cache_is_live(const struct fscache_cache *cache) 37 { 38 return fscache_cache_state(cache) == FSCACHE_CACHE_IS_ACTIVE; 39 } 40 41 static inline void fscache_set_cache_state(struct fscache_cache *cache, 42 enum fscache_cache_state new_state) 43 { 44 smp_store_release(&cache->state, new_state); 45 46 } 47 48 static inline bool fscache_set_cache_state_maybe(struct fscache_cache *cache, 49 enum fscache_cache_state old_state, 50 enum fscache_cache_state new_state) 51 { 52 return try_cmpxchg_release(&cache->state, &old_state, new_state); 53 } 54 55 /* 56 * cookie.c 57 */ 58 extern struct kmem_cache *fscache_cookie_jar; 59 extern const struct seq_operations fscache_cookies_seq_ops; 60 extern struct timer_list fscache_cookie_lru_timer; 61 62 extern void fscache_print_cookie(struct fscache_cookie *cookie, char prefix); 63 extern bool fscache_begin_cookie_access(struct fscache_cookie *cookie, 64 enum fscache_access_trace why); 65 66 static inline void fscache_see_cookie(struct fscache_cookie *cookie, 67 enum fscache_cookie_trace where) 68 { 69 trace_fscache_cookie(cookie->debug_id, refcount_read(&cookie->ref), 70 where); 71 } 72 73 /* 74 * main.c 75 */ 76 extern unsigned fscache_debug; 77 78 extern unsigned int fscache_hash(unsigned int salt, const void *data, size_t len); 79 80 /* 81 * proc.c 82 */ 83 #ifdef CONFIG_PROC_FS 84 extern int __init fscache_proc_init(void); 85 extern void fscache_proc_cleanup(void); 86 #else 87 #define fscache_proc_init() (0) 88 #define fscache_proc_cleanup() do {} while (0) 89 #endif 90 91 /* 92 * stats.c 93 */ 94 #ifdef CONFIG_FSCACHE_STATS 95 extern atomic_t fscache_n_volumes; 96 extern atomic_t fscache_n_volumes_collision; 97 extern atomic_t fscache_n_volumes_nomem; 98 extern atomic_t fscache_n_cookies; 99 extern atomic_t fscache_n_cookies_lru; 100 extern atomic_t fscache_n_cookies_lru_expired; 101 extern atomic_t fscache_n_cookies_lru_removed; 102 extern atomic_t fscache_n_cookies_lru_dropped; 103 104 extern atomic_t fscache_n_acquires; 105 extern atomic_t fscache_n_acquires_ok; 106 extern atomic_t fscache_n_acquires_oom; 107 108 extern atomic_t fscache_n_invalidates; 109 110 extern atomic_t fscache_n_relinquishes; 111 extern atomic_t fscache_n_relinquishes_retire; 112 extern atomic_t fscache_n_relinquishes_dropped; 113 114 extern atomic_t fscache_n_resizes; 115 extern atomic_t fscache_n_resizes_null; 116 117 static inline void fscache_stat(atomic_t *stat) 118 { 119 atomic_inc(stat); 120 } 121 122 static inline void fscache_stat_d(atomic_t *stat) 123 { 124 atomic_dec(stat); 125 } 126 127 #define __fscache_stat(stat) (stat) 128 129 int fscache_stats_show(struct seq_file *m, void *v); 130 #else 131 132 #define __fscache_stat(stat) (NULL) 133 #define fscache_stat(stat) do {} while (0) 134 #define fscache_stat_d(stat) do {} while (0) 135 #endif 136 137 /* 138 * volume.c 139 */ 140 extern const struct seq_operations fscache_volumes_seq_ops; 141 142 struct fscache_volume *fscache_get_volume(struct fscache_volume *volume, 143 enum fscache_volume_trace where); 144 void fscache_put_volume(struct fscache_volume *volume, 145 enum fscache_volume_trace where); 146 bool fscache_begin_volume_access(struct fscache_volume *volume, 147 struct fscache_cookie *cookie, 148 enum fscache_access_trace why); 149 void fscache_create_volume(struct fscache_volume *volume, bool wait); 150 151 152 /*****************************************************************************/ 153 /* 154 * debug tracing 155 */ 156 #define dbgprintk(FMT, ...) \ 157 printk("[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__) 158 159 #define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__) 160 #define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 161 #define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__) 162 163 #define kjournal(FMT, ...) no_printk(FMT, ##__VA_ARGS__) 164 165 #ifdef __KDEBUG 166 #define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__) 167 #define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__) 168 #define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__) 169 170 #elif defined(CONFIG_FSCACHE_DEBUG) 171 #define _enter(FMT, ...) \ 172 do { \ 173 if (__do_kdebug(ENTER)) \ 174 kenter(FMT, ##__VA_ARGS__); \ 175 } while (0) 176 177 #define _leave(FMT, ...) \ 178 do { \ 179 if (__do_kdebug(LEAVE)) \ 180 kleave(FMT, ##__VA_ARGS__); \ 181 } while (0) 182 183 #define _debug(FMT, ...) \ 184 do { \ 185 if (__do_kdebug(DEBUG)) \ 186 kdebug(FMT, ##__VA_ARGS__); \ 187 } while (0) 188 189 #else 190 #define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__) 191 #define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 192 #define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__) 193 #endif 194 195 /* 196 * determine whether a particular optional debugging point should be logged 197 * - we need to go through three steps to persuade cpp to correctly join the 198 * shorthand in FSCACHE_DEBUG_LEVEL with its prefix 199 */ 200 #define ____do_kdebug(LEVEL, POINT) \ 201 unlikely((fscache_debug & \ 202 (FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3)))) 203 #define ___do_kdebug(LEVEL, POINT) \ 204 ____do_kdebug(LEVEL, POINT) 205 #define __do_kdebug(POINT) \ 206 ___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT) 207 208 #define FSCACHE_DEBUG_CACHE 0 209 #define FSCACHE_DEBUG_COOKIE 1 210 #define FSCACHE_DEBUG_OBJECT 2 211 #define FSCACHE_DEBUG_OPERATION 3 212 213 #define FSCACHE_POINT_ENTER 1 214 #define FSCACHE_POINT_LEAVE 2 215 #define FSCACHE_POINT_DEBUG 4 216 217 #ifndef FSCACHE_DEBUG_LEVEL 218 #define FSCACHE_DEBUG_LEVEL CACHE 219 #endif 220 221 /* 222 * assertions 223 */ 224 #if 1 /* defined(__KDEBUGALL) */ 225 226 #define ASSERT(X) \ 227 do { \ 228 if (unlikely(!(X))) { \ 229 pr_err("\n"); \ 230 pr_err("Assertion failed\n"); \ 231 BUG(); \ 232 } \ 233 } while (0) 234 235 #define ASSERTCMP(X, OP, Y) \ 236 do { \ 237 if (unlikely(!((X) OP (Y)))) { \ 238 pr_err("\n"); \ 239 pr_err("Assertion failed\n"); \ 240 pr_err("%lx " #OP " %lx is false\n", \ 241 (unsigned long)(X), (unsigned long)(Y)); \ 242 BUG(); \ 243 } \ 244 } while (0) 245 246 #define ASSERTIF(C, X) \ 247 do { \ 248 if (unlikely((C) && !(X))) { \ 249 pr_err("\n"); \ 250 pr_err("Assertion failed\n"); \ 251 BUG(); \ 252 } \ 253 } while (0) 254 255 #define ASSERTIFCMP(C, X, OP, Y) \ 256 do { \ 257 if (unlikely((C) && !((X) OP (Y)))) { \ 258 pr_err("\n"); \ 259 pr_err("Assertion failed\n"); \ 260 pr_err("%lx " #OP " %lx is false\n", \ 261 (unsigned long)(X), (unsigned long)(Y)); \ 262 BUG(); \ 263 } \ 264 } while (0) 265 266 #else 267 268 #define ASSERT(X) do {} while (0) 269 #define ASSERTCMP(X, OP, Y) do {} while (0) 270 #define ASSERTIF(C, X) do {} while (0) 271 #define ASSERTIFCMP(C, X, OP, Y) do {} while (0) 272 273 #endif /* assert or not */ 274