Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
077b1f83 DM |
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 | ||
3cb29d11 VD |
9 | #define CLEANCACHE_NO_POOL -1 |
10 | #define CLEANCACHE_NO_BACKEND -2 | |
11 | #define CLEANCACHE_NO_BACKEND_SHARED -3 | |
12 | ||
077b1f83 DM |
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 | */ | |
21 | struct cleancache_filekey { | |
22 | union { | |
23 | ino_t ino; | |
24 | __u32 fh[CLEANCACHE_KEY_MAX]; | |
25 | u32 key[CLEANCACHE_KEY_MAX]; | |
26 | } u; | |
27 | }; | |
28 | ||
29 | struct cleancache_ops { | |
30 | int (*init_fs)(size_t); | |
85787090 | 31 | int (*init_shared_fs)(uuid_t *uuid, size_t); |
077b1f83 DM |
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 *); | |
91c6cc9b DM |
36 | void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t); |
37 | void (*invalidate_inode)(int, struct cleancache_filekey); | |
38 | void (*invalidate_fs)(int); | |
077b1f83 DM |
39 | }; |
40 | ||
b3c6de49 | 41 | extern int cleancache_register_ops(const struct cleancache_ops *ops); |
077b1f83 | 42 | extern void __cleancache_init_fs(struct super_block *); |
9de16262 | 43 | extern void __cleancache_init_shared_fs(struct super_block *); |
077b1f83 DM |
44 | extern int __cleancache_get_page(struct page *); |
45 | extern void __cleancache_put_page(struct page *); | |
3167760f DM |
46 | extern void __cleancache_invalidate_page(struct address_space *, struct page *); |
47 | extern void __cleancache_invalidate_inode(struct address_space *); | |
48 | extern void __cleancache_invalidate_fs(struct super_block *); | |
077b1f83 DM |
49 | |
50 | #ifdef CONFIG_CLEANCACHE | |
ff610a1d | 51 | #define cleancache_enabled (1) |
077b1f83 DM |
52 | static inline bool cleancache_fs_enabled_mapping(struct address_space *mapping) |
53 | { | |
54 | return mapping->host->i_sb->cleancache_poolid >= 0; | |
55 | } | |
a39bb9a0 CG |
56 | static inline bool cleancache_fs_enabled(struct page *page) |
57 | { | |
58 | return cleancache_fs_enabled_mapping(page->mapping); | |
59 | } | |
077b1f83 DM |
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 | ||
79 | static inline void cleancache_init_fs(struct super_block *sb) | |
80 | { | |
81 | if (cleancache_enabled) | |
82 | __cleancache_init_fs(sb); | |
83 | } | |
84 | ||
9de16262 | 85 | static inline void cleancache_init_shared_fs(struct super_block *sb) |
077b1f83 DM |
86 | { |
87 | if (cleancache_enabled) | |
9de16262 | 88 | __cleancache_init_shared_fs(sb); |
077b1f83 DM |
89 | } |
90 | ||
91 | static inline int cleancache_get_page(struct page *page) | |
92 | { | |
077b1f83 | 93 | if (cleancache_enabled && cleancache_fs_enabled(page)) |
a39bb9a0 CG |
94 | return __cleancache_get_page(page); |
95 | return -1; | |
077b1f83 DM |
96 | } |
97 | ||
98 | static inline void cleancache_put_page(struct page *page) | |
99 | { | |
100 | if (cleancache_enabled && cleancache_fs_enabled(page)) | |
101 | __cleancache_put_page(page); | |
102 | } | |
103 | ||
3167760f | 104 | static inline void cleancache_invalidate_page(struct address_space *mapping, |
077b1f83 DM |
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)) | |
3167760f | 109 | __cleancache_invalidate_page(mapping, page); |
077b1f83 DM |
110 | } |
111 | ||
3167760f | 112 | static inline void cleancache_invalidate_inode(struct address_space *mapping) |
077b1f83 DM |
113 | { |
114 | if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) | |
3167760f | 115 | __cleancache_invalidate_inode(mapping); |
077b1f83 DM |
116 | } |
117 | ||
3167760f | 118 | static inline void cleancache_invalidate_fs(struct super_block *sb) |
077b1f83 DM |
119 | { |
120 | if (cleancache_enabled) | |
3167760f | 121 | __cleancache_invalidate_fs(sb); |
077b1f83 DM |
122 | } |
123 | ||
124 | #endif /* _LINUX_CLEANCACHE_H */ |