177443f61SDavid Howells /* SPDX-License-Identifier: GPL-2.0-or-later */ 277443f61SDavid Howells /* General netfs cache on cache files internal defs 377443f61SDavid Howells * 477443f61SDavid Howells * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. 577443f61SDavid Howells * Written by David Howells (dhowells@redhat.com) 677443f61SDavid Howells */ 777443f61SDavid Howells 877443f61SDavid Howells #ifdef pr_fmt 977443f61SDavid Howells #undef pr_fmt 1077443f61SDavid Howells #endif 1177443f61SDavid Howells 1277443f61SDavid Howells #define pr_fmt(fmt) "CacheFiles: " fmt 1377443f61SDavid Howells 1477443f61SDavid Howells 1577443f61SDavid Howells #include <linux/fscache-cache.h> 1677443f61SDavid Howells #include <linux/cred.h> 1777443f61SDavid Howells #include <linux/security.h> 1877443f61SDavid Howells 198390fbc4SDavid Howells struct cachefiles_cache; 208390fbc4SDavid Howells struct cachefiles_object; 218390fbc4SDavid Howells 228390fbc4SDavid Howells /* 238390fbc4SDavid Howells * Data file records. 248390fbc4SDavid Howells */ 258390fbc4SDavid Howells struct cachefiles_object { 268390fbc4SDavid Howells int debug_id; /* debugging ID */ 278390fbc4SDavid Howells }; 288390fbc4SDavid Howells 298390fbc4SDavid Howells /* 308390fbc4SDavid Howells * Cache files cache definition 318390fbc4SDavid Howells */ 328390fbc4SDavid Howells struct cachefiles_cache { 338390fbc4SDavid Howells struct vfsmount *mnt; /* mountpoint holding the cache */ 348390fbc4SDavid Howells struct file *cachefilesd; /* manager daemon handle */ 358390fbc4SDavid Howells const struct cred *cache_cred; /* security override for accessing cache */ 368390fbc4SDavid Howells struct mutex daemon_mutex; /* command serialisation mutex */ 378390fbc4SDavid Howells wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */ 388390fbc4SDavid Howells atomic_t gravecounter; /* graveyard uniquifier */ 398390fbc4SDavid Howells atomic_t f_released; /* number of objects released lately */ 408390fbc4SDavid Howells atomic_long_t b_released; /* number of blocks released lately */ 418390fbc4SDavid Howells unsigned frun_percent; /* when to stop culling (% files) */ 428390fbc4SDavid Howells unsigned fcull_percent; /* when to start culling (% files) */ 438390fbc4SDavid Howells unsigned fstop_percent; /* when to stop allocating (% files) */ 448390fbc4SDavid Howells unsigned brun_percent; /* when to stop culling (% blocks) */ 458390fbc4SDavid Howells unsigned bcull_percent; /* when to start culling (% blocks) */ 468390fbc4SDavid Howells unsigned bstop_percent; /* when to stop allocating (% blocks) */ 478390fbc4SDavid Howells unsigned bsize; /* cache's block size */ 488390fbc4SDavid Howells unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */ 498390fbc4SDavid Howells uint64_t frun; /* when to stop culling */ 508390fbc4SDavid Howells uint64_t fcull; /* when to start culling */ 518390fbc4SDavid Howells uint64_t fstop; /* when to stop allocating */ 528390fbc4SDavid Howells sector_t brun; /* when to stop culling */ 538390fbc4SDavid Howells sector_t bcull; /* when to start culling */ 548390fbc4SDavid Howells sector_t bstop; /* when to stop allocating */ 558390fbc4SDavid Howells unsigned long flags; 568390fbc4SDavid Howells #define CACHEFILES_READY 0 /* T if cache prepared */ 578390fbc4SDavid Howells #define CACHEFILES_DEAD 1 /* T if cache dead */ 588390fbc4SDavid Howells #define CACHEFILES_CULLING 2 /* T if cull engaged */ 598390fbc4SDavid Howells #define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */ 608390fbc4SDavid Howells char *rootdirname; /* name of cache root directory */ 618390fbc4SDavid Howells char *secctx; /* LSM security context */ 628390fbc4SDavid Howells char *tag; /* cache binding tag */ 638390fbc4SDavid Howells }; 648390fbc4SDavid Howells 65*ecf5a6ceSDavid Howells #include <trace/events/cachefiles.h> 6677443f61SDavid Howells 6777443f61SDavid Howells /* 68a70f6526SDavid Howells * error_inject.c 69a70f6526SDavid Howells */ 70a70f6526SDavid Howells #ifdef CONFIG_CACHEFILES_ERROR_INJECTION 71a70f6526SDavid Howells extern unsigned int cachefiles_error_injection_state; 72a70f6526SDavid Howells extern int cachefiles_register_error_injection(void); 73a70f6526SDavid Howells extern void cachefiles_unregister_error_injection(void); 74a70f6526SDavid Howells 75a70f6526SDavid Howells #else 76a70f6526SDavid Howells #define cachefiles_error_injection_state 0 77a70f6526SDavid Howells 78a70f6526SDavid Howells static inline int cachefiles_register_error_injection(void) 79a70f6526SDavid Howells { 80a70f6526SDavid Howells return 0; 81a70f6526SDavid Howells } 82a70f6526SDavid Howells 83a70f6526SDavid Howells static inline void cachefiles_unregister_error_injection(void) 84a70f6526SDavid Howells { 85a70f6526SDavid Howells } 86a70f6526SDavid Howells #endif 87a70f6526SDavid Howells 88a70f6526SDavid Howells 89a70f6526SDavid Howells static inline int cachefiles_inject_read_error(void) 90a70f6526SDavid Howells { 91a70f6526SDavid Howells return cachefiles_error_injection_state & 2 ? -EIO : 0; 92a70f6526SDavid Howells } 93a70f6526SDavid Howells 94a70f6526SDavid Howells static inline int cachefiles_inject_write_error(void) 95a70f6526SDavid Howells { 96a70f6526SDavid Howells return cachefiles_error_injection_state & 2 ? -EIO : 97a70f6526SDavid Howells cachefiles_error_injection_state & 1 ? -ENOSPC : 98a70f6526SDavid Howells 0; 99a70f6526SDavid Howells } 100a70f6526SDavid Howells 101a70f6526SDavid Howells static inline int cachefiles_inject_remove_error(void) 102a70f6526SDavid Howells { 103a70f6526SDavid Howells return cachefiles_error_injection_state & 2 ? -EIO : 0; 104a70f6526SDavid Howells } 105a70f6526SDavid Howells 106a70f6526SDavid Howells 107a70f6526SDavid Howells /* 108a70f6526SDavid Howells * Debug tracing 10977443f61SDavid Howells */ 11077443f61SDavid Howells extern unsigned cachefiles_debug; 11177443f61SDavid Howells #define CACHEFILES_DEBUG_KENTER 1 11277443f61SDavid Howells #define CACHEFILES_DEBUG_KLEAVE 2 11377443f61SDavid Howells #define CACHEFILES_DEBUG_KDEBUG 4 11477443f61SDavid Howells 11577443f61SDavid Howells #define dbgprintk(FMT, ...) \ 11677443f61SDavid Howells printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__) 11777443f61SDavid Howells 11877443f61SDavid Howells #define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__) 11977443f61SDavid Howells #define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 12077443f61SDavid Howells #define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__) 12177443f61SDavid Howells 12277443f61SDavid Howells 12377443f61SDavid Howells #if defined(__KDEBUG) 12477443f61SDavid Howells #define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__) 12577443f61SDavid Howells #define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__) 12677443f61SDavid Howells #define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__) 12777443f61SDavid Howells 12877443f61SDavid Howells #elif defined(CONFIG_CACHEFILES_DEBUG) 12977443f61SDavid Howells #define _enter(FMT, ...) \ 13077443f61SDavid Howells do { \ 13177443f61SDavid Howells if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \ 13277443f61SDavid Howells kenter(FMT, ##__VA_ARGS__); \ 13377443f61SDavid Howells } while (0) 13477443f61SDavid Howells 13577443f61SDavid Howells #define _leave(FMT, ...) \ 13677443f61SDavid Howells do { \ 13777443f61SDavid Howells if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \ 13877443f61SDavid Howells kleave(FMT, ##__VA_ARGS__); \ 13977443f61SDavid Howells } while (0) 14077443f61SDavid Howells 14177443f61SDavid Howells #define _debug(FMT, ...) \ 14277443f61SDavid Howells do { \ 14377443f61SDavid Howells if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \ 14477443f61SDavid Howells kdebug(FMT, ##__VA_ARGS__); \ 14577443f61SDavid Howells } while (0) 14677443f61SDavid Howells 14777443f61SDavid Howells #else 14877443f61SDavid Howells #define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__) 14977443f61SDavid Howells #define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__) 15077443f61SDavid Howells #define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__) 15177443f61SDavid Howells #endif 15277443f61SDavid Howells 15377443f61SDavid Howells #if 1 /* defined(__KDEBUGALL) */ 15477443f61SDavid Howells 15577443f61SDavid Howells #define ASSERT(X) \ 15677443f61SDavid Howells do { \ 15777443f61SDavid Howells if (unlikely(!(X))) { \ 15877443f61SDavid Howells pr_err("\n"); \ 15977443f61SDavid Howells pr_err("Assertion failed\n"); \ 16077443f61SDavid Howells BUG(); \ 16177443f61SDavid Howells } \ 16277443f61SDavid Howells } while (0) 16377443f61SDavid Howells 16477443f61SDavid Howells #define ASSERTCMP(X, OP, Y) \ 16577443f61SDavid Howells do { \ 16677443f61SDavid Howells if (unlikely(!((X) OP (Y)))) { \ 16777443f61SDavid Howells pr_err("\n"); \ 16877443f61SDavid Howells pr_err("Assertion failed\n"); \ 16977443f61SDavid Howells pr_err("%lx " #OP " %lx is false\n", \ 17077443f61SDavid Howells (unsigned long)(X), (unsigned long)(Y)); \ 17177443f61SDavid Howells BUG(); \ 17277443f61SDavid Howells } \ 17377443f61SDavid Howells } while (0) 17477443f61SDavid Howells 17577443f61SDavid Howells #define ASSERTIF(C, X) \ 17677443f61SDavid Howells do { \ 17777443f61SDavid Howells if (unlikely((C) && !(X))) { \ 17877443f61SDavid Howells pr_err("\n"); \ 17977443f61SDavid Howells pr_err("Assertion failed\n"); \ 18077443f61SDavid Howells BUG(); \ 18177443f61SDavid Howells } \ 18277443f61SDavid Howells } while (0) 18377443f61SDavid Howells 18477443f61SDavid Howells #define ASSERTIFCMP(C, X, OP, Y) \ 18577443f61SDavid Howells do { \ 18677443f61SDavid Howells if (unlikely((C) && !((X) OP (Y)))) { \ 18777443f61SDavid Howells pr_err("\n"); \ 18877443f61SDavid Howells pr_err("Assertion failed\n"); \ 18977443f61SDavid Howells pr_err("%lx " #OP " %lx is false\n", \ 19077443f61SDavid Howells (unsigned long)(X), (unsigned long)(Y)); \ 19177443f61SDavid Howells BUG(); \ 19277443f61SDavid Howells } \ 19377443f61SDavid Howells } while (0) 19477443f61SDavid Howells 19577443f61SDavid Howells #else 19677443f61SDavid Howells 19777443f61SDavid Howells #define ASSERT(X) do {} while (0) 19877443f61SDavid Howells #define ASSERTCMP(X, OP, Y) do {} while (0) 19977443f61SDavid Howells #define ASSERTIF(C, X) do {} while (0) 20077443f61SDavid Howells #define ASSERTIFCMP(C, X, OP, Y) do {} while (0) 20177443f61SDavid Howells 20277443f61SDavid Howells #endif 203