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