netfs, fscache: Combine fscache with netfs
[linux-block.git] / fs / netfs / internal.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* Internal definitions for network filesystem support
3  *
4  * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7
8 #include <linux/slab.h>
9 #include <linux/seq_file.h>
10 #include <linux/netfs.h>
11 #include <linux/fscache.h>
12 #include <linux/fscache-cache.h>
13 #include <trace/events/netfs.h>
14 #include <trace/events/fscache.h>
15
16 #ifdef pr_fmt
17 #undef pr_fmt
18 #endif
19
20 #define pr_fmt(fmt) "netfs: " fmt
21
22 /*
23  * buffered_read.c
24  */
25 void netfs_rreq_unlock_folios(struct netfs_io_request *rreq);
26
27 /*
28  * io.c
29  */
30 int netfs_begin_read(struct netfs_io_request *rreq, bool sync);
31
32 /*
33  * main.c
34  */
35 extern unsigned int netfs_debug;
36
37 /*
38  * objects.c
39  */
40 struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
41                                              struct file *file,
42                                              loff_t start, size_t len,
43                                              enum netfs_io_origin origin);
44 void netfs_get_request(struct netfs_io_request *rreq, enum netfs_rreq_ref_trace what);
45 void netfs_clear_subrequests(struct netfs_io_request *rreq, bool was_async);
46 void netfs_put_request(struct netfs_io_request *rreq, bool was_async,
47                        enum netfs_rreq_ref_trace what);
48 struct netfs_io_subrequest *netfs_alloc_subrequest(struct netfs_io_request *rreq);
49
50 static inline void netfs_see_request(struct netfs_io_request *rreq,
51                                      enum netfs_rreq_ref_trace what)
52 {
53         trace_netfs_rreq_ref(rreq->debug_id, refcount_read(&rreq->ref), what);
54 }
55
56 /*
57  * stats.c
58  */
59 #ifdef CONFIG_NETFS_STATS
60 extern atomic_t netfs_n_rh_readahead;
61 extern atomic_t netfs_n_rh_readpage;
62 extern atomic_t netfs_n_rh_rreq;
63 extern atomic_t netfs_n_rh_sreq;
64 extern atomic_t netfs_n_rh_download;
65 extern atomic_t netfs_n_rh_download_done;
66 extern atomic_t netfs_n_rh_download_failed;
67 extern atomic_t netfs_n_rh_download_instead;
68 extern atomic_t netfs_n_rh_read;
69 extern atomic_t netfs_n_rh_read_done;
70 extern atomic_t netfs_n_rh_read_failed;
71 extern atomic_t netfs_n_rh_zero;
72 extern atomic_t netfs_n_rh_short_read;
73 extern atomic_t netfs_n_rh_write;
74 extern atomic_t netfs_n_rh_write_begin;
75 extern atomic_t netfs_n_rh_write_done;
76 extern atomic_t netfs_n_rh_write_failed;
77 extern atomic_t netfs_n_rh_write_zskip;
78
79
80 static inline void netfs_stat(atomic_t *stat)
81 {
82         atomic_inc(stat);
83 }
84
85 static inline void netfs_stat_d(atomic_t *stat)
86 {
87         atomic_dec(stat);
88 }
89
90 #else
91 #define netfs_stat(x) do {} while(0)
92 #define netfs_stat_d(x) do {} while(0)
93 #endif
94
95 /*
96  * Miscellaneous functions.
97  */
98 static inline bool netfs_is_cache_enabled(struct netfs_inode *ctx)
99 {
100 #if IS_ENABLED(CONFIG_FSCACHE)
101         struct fscache_cookie *cookie = ctx->cache;
102
103         return fscache_cookie_valid(cookie) && cookie->cache_priv &&
104                 fscache_cookie_enabled(cookie);
105 #else
106         return false;
107 #endif
108 }
109
110 /*
111  * fscache-cache.c
112  */
113 #ifdef CONFIG_PROC_FS
114 extern const struct seq_operations fscache_caches_seq_ops;
115 #endif
116 bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
117 void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
118 struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache);
119 void fscache_put_cache(struct fscache_cache *cache, enum fscache_cache_trace where);
120
121 static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache)
122 {
123         return smp_load_acquire(&cache->state);
124 }
125
126 static inline bool fscache_cache_is_live(const struct fscache_cache *cache)
127 {
128         return fscache_cache_state(cache) == FSCACHE_CACHE_IS_ACTIVE;
129 }
130
131 static inline void fscache_set_cache_state(struct fscache_cache *cache,
132                                            enum fscache_cache_state new_state)
133 {
134         smp_store_release(&cache->state, new_state);
135
136 }
137
138 static inline bool fscache_set_cache_state_maybe(struct fscache_cache *cache,
139                                                  enum fscache_cache_state old_state,
140                                                  enum fscache_cache_state new_state)
141 {
142         return try_cmpxchg_release(&cache->state, &old_state, new_state);
143 }
144
145 /*
146  * fscache-cookie.c
147  */
148 extern struct kmem_cache *fscache_cookie_jar;
149 #ifdef CONFIG_PROC_FS
150 extern const struct seq_operations fscache_cookies_seq_ops;
151 #endif
152 extern struct timer_list fscache_cookie_lru_timer;
153
154 extern void fscache_print_cookie(struct fscache_cookie *cookie, char prefix);
155 extern bool fscache_begin_cookie_access(struct fscache_cookie *cookie,
156                                         enum fscache_access_trace why);
157
158 static inline void fscache_see_cookie(struct fscache_cookie *cookie,
159                                       enum fscache_cookie_trace where)
160 {
161         trace_fscache_cookie(cookie->debug_id, refcount_read(&cookie->ref),
162                              where);
163 }
164
165 /*
166  * fscache-main.c
167  */
168 extern unsigned int fscache_hash(unsigned int salt, const void *data, size_t len);
169
170 /*
171  * fscache-proc.c
172  */
173 #ifdef CONFIG_PROC_FS
174 extern int __init fscache_proc_init(void);
175 extern void fscache_proc_cleanup(void);
176 #else
177 #define fscache_proc_init()     (0)
178 #define fscache_proc_cleanup()  do {} while (0)
179 #endif
180
181 /*
182  * fscache-stats.c
183  */
184 #ifdef CONFIG_FSCACHE_STATS
185 extern atomic_t fscache_n_volumes;
186 extern atomic_t fscache_n_volumes_collision;
187 extern atomic_t fscache_n_volumes_nomem;
188 extern atomic_t fscache_n_cookies;
189 extern atomic_t fscache_n_cookies_lru;
190 extern atomic_t fscache_n_cookies_lru_expired;
191 extern atomic_t fscache_n_cookies_lru_removed;
192 extern atomic_t fscache_n_cookies_lru_dropped;
193
194 extern atomic_t fscache_n_acquires;
195 extern atomic_t fscache_n_acquires_ok;
196 extern atomic_t fscache_n_acquires_oom;
197
198 extern atomic_t fscache_n_invalidates;
199
200 extern atomic_t fscache_n_relinquishes;
201 extern atomic_t fscache_n_relinquishes_retire;
202 extern atomic_t fscache_n_relinquishes_dropped;
203
204 extern atomic_t fscache_n_resizes;
205 extern atomic_t fscache_n_resizes_null;
206
207 static inline void fscache_stat(atomic_t *stat)
208 {
209         atomic_inc(stat);
210 }
211
212 static inline void fscache_stat_d(atomic_t *stat)
213 {
214         atomic_dec(stat);
215 }
216
217 #define __fscache_stat(stat) (stat)
218
219 int fscache_stats_show(struct seq_file *m, void *v);
220 #else
221
222 #define __fscache_stat(stat) (NULL)
223 #define fscache_stat(stat) do {} while (0)
224 #define fscache_stat_d(stat) do {} while (0)
225 #endif
226
227 /*
228  * fscache-volume.c
229  */
230 #ifdef CONFIG_PROC_FS
231 extern const struct seq_operations fscache_volumes_seq_ops;
232 #endif
233
234 struct fscache_volume *fscache_get_volume(struct fscache_volume *volume,
235                                           enum fscache_volume_trace where);
236 void fscache_put_volume(struct fscache_volume *volume,
237                         enum fscache_volume_trace where);
238 bool fscache_begin_volume_access(struct fscache_volume *volume,
239                                  struct fscache_cookie *cookie,
240                                  enum fscache_access_trace why);
241 void fscache_create_volume(struct fscache_volume *volume, bool wait);
242
243 /*****************************************************************************/
244 /*
245  * debug tracing
246  */
247 #define dbgprintk(FMT, ...) \
248         printk("[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
249
250 #define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
251 #define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
252 #define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
253
254 #ifdef __KDEBUG
255 #define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
256 #define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
257 #define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
258
259 #elif defined(CONFIG_NETFS_DEBUG)
260 #define _enter(FMT, ...)                        \
261 do {                                            \
262         if (netfs_debug)                        \
263                 kenter(FMT, ##__VA_ARGS__);     \
264 } while (0)
265
266 #define _leave(FMT, ...)                        \
267 do {                                            \
268         if (netfs_debug)                        \
269                 kleave(FMT, ##__VA_ARGS__);     \
270 } while (0)
271
272 #define _debug(FMT, ...)                        \
273 do {                                            \
274         if (netfs_debug)                        \
275                 kdebug(FMT, ##__VA_ARGS__);     \
276 } while (0)
277
278 #else
279 #define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
280 #define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
281 #define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
282 #endif
283
284 /*
285  * assertions
286  */
287 #if 1 /* defined(__KDEBUGALL) */
288
289 #define ASSERT(X)                                                       \
290 do {                                                                    \
291         if (unlikely(!(X))) {                                           \
292                 pr_err("\n");                                   \
293                 pr_err("Assertion failed\n");   \
294                 BUG();                                                  \
295         }                                                               \
296 } while (0)
297
298 #define ASSERTCMP(X, OP, Y)                                             \
299 do {                                                                    \
300         if (unlikely(!((X) OP (Y)))) {                                  \
301                 pr_err("\n");                                   \
302                 pr_err("Assertion failed\n");   \
303                 pr_err("%lx " #OP " %lx is false\n",            \
304                        (unsigned long)(X), (unsigned long)(Y));         \
305                 BUG();                                                  \
306         }                                                               \
307 } while (0)
308
309 #define ASSERTIF(C, X)                                                  \
310 do {                                                                    \
311         if (unlikely((C) && !(X))) {                                    \
312                 pr_err("\n");                                   \
313                 pr_err("Assertion failed\n");   \
314                 BUG();                                                  \
315         }                                                               \
316 } while (0)
317
318 #define ASSERTIFCMP(C, X, OP, Y)                                        \
319 do {                                                                    \
320         if (unlikely((C) && !((X) OP (Y)))) {                           \
321                 pr_err("\n");                                   \
322                 pr_err("Assertion failed\n");   \
323                 pr_err("%lx " #OP " %lx is false\n",            \
324                        (unsigned long)(X), (unsigned long)(Y));         \
325                 BUG();                                                  \
326         }                                                               \
327 } while (0)
328
329 #else
330
331 #define ASSERT(X)                       do {} while (0)
332 #define ASSERTCMP(X, OP, Y)             do {} while (0)
333 #define ASSERTIF(C, X)                  do {} while (0)
334 #define ASSERTIFCMP(C, X, OP, Y)        do {} while (0)
335
336 #endif /* assert or not */