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