linux/fs/cachefiles/internal.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/* General netfs cache on cache files internal defs
   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) "CacheFiles: " fmt
  13
  14
  15#include <linux/fscache-cache.h>
  16#include <linux/cred.h>
  17#include <linux/security.h>
  18
  19#define CACHEFILES_DIO_BLOCK_SIZE 4096
  20
  21struct cachefiles_cache;
  22struct cachefiles_object;
  23
  24enum cachefiles_content {
  25        /* These values are saved on disk */
  26        CACHEFILES_CONTENT_NO_DATA      = 0, /* No content stored */
  27        CACHEFILES_CONTENT_SINGLE       = 1, /* Content is monolithic, all is present */
  28        CACHEFILES_CONTENT_ALL          = 2, /* Content is all present, no map */
  29        CACHEFILES_CONTENT_BACKFS_MAP   = 3, /* Content is piecemeal, mapped through backing fs */
  30        CACHEFILES_CONTENT_DIRTY        = 4, /* Content is dirty (only seen on disk) */
  31        nr__cachefiles_content
  32};
  33
  34/*
  35 * Cached volume representation.
  36 */
  37struct cachefiles_volume {
  38        struct cachefiles_cache         *cache;
  39        struct list_head                cache_link;     /* Link in cache->volumes */
  40        struct fscache_volume           *vcookie;       /* The netfs's representation */
  41        struct dentry                   *dentry;        /* The volume dentry */
  42        struct dentry                   *fanout[256];   /* Fanout subdirs */
  43};
  44
  45/*
  46 * Backing file state.
  47 */
  48struct cachefiles_object {
  49        struct fscache_cookie           *cookie;        /* Netfs data storage object cookie */
  50        struct cachefiles_volume        *volume;        /* Cache volume that holds this object */
  51        struct list_head                cache_link;     /* Link in cache->*_list */
  52        struct file                     *file;          /* The file representing this object */
  53        char                            *d_name;        /* Backing file name */
  54        int                             debug_id;
  55        spinlock_t                      lock;
  56        refcount_t                      ref;
  57        u8                              d_name_len;     /* Length of filename */
  58        enum cachefiles_content         content_info:8; /* Info about content presence */
  59        unsigned long                   flags;
  60#define CACHEFILES_OBJECT_USING_TMPFILE 0               /* Have an unlinked tmpfile */
  61};
  62
  63/*
  64 * Cache files cache definition
  65 */
  66struct cachefiles_cache {
  67        struct fscache_cache            *cache;         /* Cache cookie */
  68        struct vfsmount                 *mnt;           /* mountpoint holding the cache */
  69        struct dentry                   *store;         /* Directory into which live objects go */
  70        struct dentry                   *graveyard;     /* directory into which dead objects go */
  71        struct file                     *cachefilesd;   /* manager daemon handle */
  72        struct list_head                volumes;        /* List of volume objects */
  73        struct list_head                object_list;    /* List of active objects */
  74        spinlock_t                      object_list_lock; /* Lock for volumes and object_list */
  75        const struct cred               *cache_cred;    /* security override for accessing cache */
  76        struct mutex                    daemon_mutex;   /* command serialisation mutex */
  77        wait_queue_head_t               daemon_pollwq;  /* poll waitqueue for daemon */
  78        atomic_t                        gravecounter;   /* graveyard uniquifier */
  79        atomic_t                        f_released;     /* number of objects released lately */
  80        atomic_long_t                   b_released;     /* number of blocks released lately */
  81        atomic_long_t                   b_writing;      /* Number of blocks being written */
  82        unsigned                        frun_percent;   /* when to stop culling (% files) */
  83        unsigned                        fcull_percent;  /* when to start culling (% files) */
  84        unsigned                        fstop_percent;  /* when to stop allocating (% files) */
  85        unsigned                        brun_percent;   /* when to stop culling (% blocks) */
  86        unsigned                        bcull_percent;  /* when to start culling (% blocks) */
  87        unsigned                        bstop_percent;  /* when to stop allocating (% blocks) */
  88        unsigned                        bsize;          /* cache's block size */
  89        unsigned                        bshift;         /* ilog2(bsize) */
  90        uint64_t                        frun;           /* when to stop culling */
  91        uint64_t                        fcull;          /* when to start culling */
  92        uint64_t                        fstop;          /* when to stop allocating */
  93        sector_t                        brun;           /* when to stop culling */
  94        sector_t                        bcull;          /* when to start culling */
  95        sector_t                        bstop;          /* when to stop allocating */
  96        unsigned long                   flags;
  97#define CACHEFILES_READY                0       /* T if cache prepared */
  98#define CACHEFILES_DEAD                 1       /* T if cache dead */
  99#define CACHEFILES_CULLING              2       /* T if cull engaged */
 100#define CACHEFILES_STATE_CHANGED        3       /* T if state changed (poll trigger) */
 101        char                            *rootdirname;   /* name of cache root directory */
 102        char                            *secctx;        /* LSM security context */
 103        char                            *tag;           /* cache binding tag */
 104};
 105
 106#include <trace/events/cachefiles.h>
 107
 108static inline
 109struct file *cachefiles_cres_file(struct netfs_cache_resources *cres)
 110{
 111        return cres->cache_priv2;
 112}
 113
 114static inline
 115struct cachefiles_object *cachefiles_cres_object(struct netfs_cache_resources *cres)
 116{
 117        return fscache_cres_cookie(cres)->cache_priv;
 118}
 119
 120/*
 121 * note change of state for daemon
 122 */
 123static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
 124{
 125        set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
 126        wake_up_all(&cache->daemon_pollwq);
 127}
 128
 129/*
 130 * cache.c
 131 */
 132extern int cachefiles_add_cache(struct cachefiles_cache *cache);
 133extern void cachefiles_withdraw_cache(struct cachefiles_cache *cache);
 134
 135enum cachefiles_has_space_for {
 136        cachefiles_has_space_check,
 137        cachefiles_has_space_for_write,
 138        cachefiles_has_space_for_create,
 139};
 140extern int cachefiles_has_space(struct cachefiles_cache *cache,
 141                                unsigned fnr, unsigned bnr,
 142                                enum cachefiles_has_space_for reason);
 143
 144/*
 145 * daemon.c
 146 */
 147extern const struct file_operations cachefiles_daemon_fops;
 148
 149/*
 150 * error_inject.c
 151 */
 152#ifdef CONFIG_CACHEFILES_ERROR_INJECTION
 153extern unsigned int cachefiles_error_injection_state;
 154extern int cachefiles_register_error_injection(void);
 155extern void cachefiles_unregister_error_injection(void);
 156
 157#else
 158#define cachefiles_error_injection_state 0
 159
 160static inline int cachefiles_register_error_injection(void)
 161{
 162        return 0;
 163}
 164
 165static inline void cachefiles_unregister_error_injection(void)
 166{
 167}
 168#endif
 169
 170
 171static inline int cachefiles_inject_read_error(void)
 172{
 173        return cachefiles_error_injection_state & 2 ? -EIO : 0;
 174}
 175
 176static inline int cachefiles_inject_write_error(void)
 177{
 178        return cachefiles_error_injection_state & 2 ? -EIO :
 179                cachefiles_error_injection_state & 1 ? -ENOSPC :
 180                0;
 181}
 182
 183static inline int cachefiles_inject_remove_error(void)
 184{
 185        return cachefiles_error_injection_state & 2 ? -EIO : 0;
 186}
 187
 188/*
 189 * interface.c
 190 */
 191extern const struct fscache_cache_ops cachefiles_cache_ops;
 192extern void cachefiles_see_object(struct cachefiles_object *object,
 193                                  enum cachefiles_obj_ref_trace why);
 194extern struct cachefiles_object *cachefiles_grab_object(struct cachefiles_object *object,
 195                                                        enum cachefiles_obj_ref_trace why);
 196extern void cachefiles_put_object(struct cachefiles_object *object,
 197                                  enum cachefiles_obj_ref_trace why);
 198
 199/*
 200 * io.c
 201 */
 202extern bool cachefiles_begin_operation(struct netfs_cache_resources *cres,
 203                                       enum fscache_want_state want_state);
 204
 205/*
 206 * key.c
 207 */
 208extern bool cachefiles_cook_key(struct cachefiles_object *object);
 209
 210/*
 211 * main.c
 212 */
 213extern struct kmem_cache *cachefiles_object_jar;
 214
 215/*
 216 * namei.c
 217 */
 218extern void cachefiles_unmark_inode_in_use(struct cachefiles_object *object,
 219                                           struct file *file);
 220extern int cachefiles_bury_object(struct cachefiles_cache *cache,
 221                                  struct cachefiles_object *object,
 222                                  struct dentry *dir,
 223                                  struct dentry *rep,
 224                                  enum fscache_why_object_killed why);
 225extern int cachefiles_delete_object(struct cachefiles_object *object,
 226                                    enum fscache_why_object_killed why);
 227extern bool cachefiles_look_up_object(struct cachefiles_object *object);
 228extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
 229                                               struct dentry *dir,
 230                                               const char *name,
 231                                               bool *_is_new);
 232extern void cachefiles_put_directory(struct dentry *dir);
 233
 234extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
 235                           char *filename);
 236
 237extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
 238                                   struct dentry *dir, char *filename);
 239extern struct file *cachefiles_create_tmpfile(struct cachefiles_object *object);
 240extern bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
 241                                      struct cachefiles_object *object);
 242
 243/*
 244 * security.c
 245 */
 246extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
 247extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
 248                                               struct dentry *root,
 249                                               const struct cred **_saved_cred);
 250
 251static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
 252                                           const struct cred **_saved_cred)
 253{
 254        *_saved_cred = override_creds(cache->cache_cred);
 255}
 256
 257static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
 258                                         const struct cred *saved_cred)
 259{
 260        revert_creds(saved_cred);
 261}
 262
 263/*
 264 * volume.c
 265 */
 266void cachefiles_acquire_volume(struct fscache_volume *volume);
 267void cachefiles_free_volume(struct fscache_volume *volume);
 268void cachefiles_withdraw_volume(struct cachefiles_volume *volume);
 269
 270/*
 271 * xattr.c
 272 */
 273extern int cachefiles_set_object_xattr(struct cachefiles_object *object);
 274extern int cachefiles_check_auxdata(struct cachefiles_object *object,
 275                                    struct file *file);
 276extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
 277                                          struct cachefiles_object *object,
 278                                          struct dentry *dentry);
 279extern void cachefiles_prepare_to_write(struct fscache_cookie *cookie);
 280extern bool cachefiles_set_volume_xattr(struct cachefiles_volume *volume);
 281extern int cachefiles_check_volume_xattr(struct cachefiles_volume *volume);
 282
 283/*
 284 * Error handling
 285 */
 286#define cachefiles_io_error(___cache, FMT, ...)         \
 287do {                                                    \
 288        pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__);   \
 289        fscache_io_error((___cache)->cache);            \
 290        set_bit(CACHEFILES_DEAD, &(___cache)->flags);   \
 291} while (0)
 292
 293#define cachefiles_io_error_obj(object, FMT, ...)                       \
 294do {                                                                    \
 295        struct cachefiles_cache *___cache;                              \
 296                                                                        \
 297        ___cache = (object)->volume->cache;                             \
 298        cachefiles_io_error(___cache, FMT " [o=%08x]", ##__VA_ARGS__,   \
 299                            (object)->debug_id);                        \
 300} while (0)
 301
 302
 303/*
 304 * Debug tracing
 305 */
 306extern unsigned cachefiles_debug;
 307#define CACHEFILES_DEBUG_KENTER 1
 308#define CACHEFILES_DEBUG_KLEAVE 2
 309#define CACHEFILES_DEBUG_KDEBUG 4
 310
 311#define dbgprintk(FMT, ...) \
 312        printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
 313
 314#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
 315#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
 316#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
 317
 318
 319#if defined(__KDEBUG)
 320#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
 321#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
 322#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
 323
 324#elif defined(CONFIG_CACHEFILES_DEBUG)
 325#define _enter(FMT, ...)                                \
 326do {                                                    \
 327        if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
 328                kenter(FMT, ##__VA_ARGS__);             \
 329} while (0)
 330
 331#define _leave(FMT, ...)                                \
 332do {                                                    \
 333        if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
 334                kleave(FMT, ##__VA_ARGS__);             \
 335} while (0)
 336
 337#define _debug(FMT, ...)                                \
 338do {                                                    \
 339        if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
 340                kdebug(FMT, ##__VA_ARGS__);             \
 341} while (0)
 342
 343#else
 344#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
 345#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
 346#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
 347#endif
 348
 349#if 1 /* defined(__KDEBUGALL) */
 350
 351#define ASSERT(X)                                                       \
 352do {                                                                    \
 353        if (unlikely(!(X))) {                                           \
 354                pr_err("\n");                                           \
 355                pr_err("Assertion failed\n");           \
 356                BUG();                                                  \
 357        }                                                               \
 358} while (0)
 359
 360#define ASSERTCMP(X, OP, Y)                                             \
 361do {                                                                    \
 362        if (unlikely(!((X) OP (Y)))) {                                  \
 363                pr_err("\n");                                           \
 364                pr_err("Assertion failed\n");           \
 365                pr_err("%lx " #OP " %lx is false\n",                    \
 366                       (unsigned long)(X), (unsigned long)(Y));         \
 367                BUG();                                                  \
 368        }                                                               \
 369} while (0)
 370
 371#define ASSERTIF(C, X)                                                  \
 372do {                                                                    \
 373        if (unlikely((C) && !(X))) {                                    \
 374                pr_err("\n");                                           \
 375                pr_err("Assertion failed\n");           \
 376                BUG();                                                  \
 377        }                                                               \
 378} while (0)
 379
 380#define ASSERTIFCMP(C, X, OP, Y)                                        \
 381do {                                                                    \
 382        if (unlikely((C) && !((X) OP (Y)))) {                           \
 383                pr_err("\n");                                           \
 384                pr_err("Assertion failed\n");           \
 385                pr_err("%lx " #OP " %lx is false\n",                    \
 386                       (unsigned long)(X), (unsigned long)(Y));         \
 387                BUG();                                                  \
 388        }                                                               \
 389} while (0)
 390
 391#else
 392
 393#define ASSERT(X)                       do {} while (0)
 394#define ASSERTCMP(X, OP, Y)             do {} while (0)
 395#define ASSERTIF(C, X)                  do {} while (0)
 396#define ASSERTIFCMP(C, X, OP, Y)        do {} while (0)
 397
 398#endif
 399