at v5.2 4.0 kB view raw
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 */