linux/include/linux/cleancache.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_CLEANCACHE_H
   3#define _LINUX_CLEANCACHE_H
   4
   5#include <linux/fs.h>
   6#include <linux/exportfs.h>
   7#include <linux/mm.h>
   8
   9#define CLEANCACHE_NO_POOL              -1
  10#define CLEANCACHE_NO_BACKEND           -2
  11#define CLEANCACHE_NO_BACKEND_SHARED    -3
  12
  13#define CLEANCACHE_KEY_MAX 6
  14
  15/*
  16 * cleancache requires every file with a page in cleancache to have a
  17 * unique key unless/until the file is removed/truncated.  For some
  18 * filesystems, the inode number is unique, but for "modern" filesystems
  19 * an exportable filehandle is required (see exportfs.h)
  20 */
  21struct cleancache_filekey {
  22        union {
  23                ino_t ino;
  24                __u32 fh[CLEANCACHE_KEY_MAX];
  25                u32 key[CLEANCACHE_KEY_MAX];
  26        } u;
  27};
  28
  29struct cleancache_ops {
  30        int (*init_fs)(size_t);
  31        int (*init_shared_fs)(uuid_t *uuid, size_t);
  32        int (*get_page)(int, struct cleancache_filekey,
  33                        pgoff_t, struct page *);
  34        void (*put_page)(int, struct cleancache_filekey,
  35                        pgoff_t, struct page *);
  36        void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t);
  37        void (*invalidate_inode)(int, struct cleancache_filekey);
  38        void (*invalidate_fs)(int);
  39};
  40
  41extern int cleancache_register_ops(const struct cleancache_ops *ops);
  42extern void __cleancache_init_fs(struct super_block *);
  43extern void __cleancache_init_shared_fs(struct super_block *);
  44extern int  __cleancache_get_page(struct page *);
  45extern void __cleancache_put_page(struct page *);
  46extern void __cleancache_invalidate_page(struct address_space *, struct page *);
  47extern void __cleancache_invalidate_inode(struct address_space *);
  48extern void __cleancache_invalidate_fs(struct super_block *);
  49
  50#ifdef CONFIG_CLEANCACHE
  51#define cleancache_enabled (1)
  52static inline bool cleancache_fs_enabled_mapping(struct address_space *mapping)
  53{
  54        return mapping->host->i_sb->cleancache_poolid >= 0;
  55}
  56static inline bool cleancache_fs_enabled(struct page *page)
  57{
  58        return cleancache_fs_enabled_mapping(page->mapping);
  59}
  60#else
  61#define cleancache_enabled (0)
  62#define cleancache_fs_enabled(_page) (0)
  63#define cleancache_fs_enabled_mapping(_page) (0)
  64#endif
  65
  66/*
  67 * The shim layer provided by these inline functions allows the compiler
  68 * to reduce all cleancache hooks to nothingness if CONFIG_CLEANCACHE
  69 * is disabled, to a single global variable check if CONFIG_CLEANCACHE
  70 * is enabled but no cleancache "backend" has dynamically enabled it,
  71 * and, for the most frequent cleancache ops, to a single global variable
  72 * check plus a superblock element comparison if CONFIG_CLEANCACHE is enabled
  73 * and a cleancache backend has dynamically enabled cleancache, but the
  74 * filesystem referenced by that cleancache op has not enabled cleancache.
  75 * As a result, CONFIG_CLEANCACHE can be enabled by default with essentially
  76 * no measurable performance impact.
  77 */
  78
  79static inline void cleancache_init_fs(struct super_block *sb)
  80{
  81        if (cleancache_enabled)
  82                __cleancache_init_fs(sb);
  83}
  84
  85static inline void cleancache_init_shared_fs(struct super_block *sb)
  86{
  87        if (cleancache_enabled)
  88                __cleancache_init_shared_fs(sb);
  89}
  90
  91static inline int cleancache_get_page(struct page *page)
  92{
  93        if (cleancache_enabled && cleancache_fs_enabled(page))
  94                return __cleancache_get_page(page);
  95        return -1;
  96}
  97
  98static inline void cleancache_put_page(struct page *page)
  99{
 100        if (cleancache_enabled && cleancache_fs_enabled(page))
 101                __cleancache_put_page(page);
 102}
 103
 104static inline void cleancache_invalidate_page(struct address_space *mapping,
 105                                        struct page *page)
 106{
 107        /* careful... page->mapping is NULL sometimes when this is called */
 108        if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
 109                __cleancache_invalidate_page(mapping, page);
 110}
 111
 112static inline void cleancache_invalidate_inode(struct address_space *mapping)
 113{
 114        if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping))
 115                __cleancache_invalidate_inode(mapping);
 116}
 117
 118static inline void cleancache_invalidate_fs(struct super_block *sb)
 119{
 120        if (cleancache_enabled)
 121                __cleancache_invalidate_fs(sb);
 122}
 123
 124#endif /* _LINUX_CLEANCACHE_H */
 125