1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * The NFSD open file cache.
4 *
5 * (c) 2015 - Jeff Layton <jeff.layton@primarydata.com>
6 *
7 * An nfsd_file object is a per-file collection of open state that binds
8 * together:
9 * - a struct file *
10 * - a user credential
11 * - a network namespace
12 * - a read-ahead context
13 * - monitoring for writeback errors
14 *
15 * nfsd_file objects are reference-counted. Consumers acquire a new
16 * object via the nfsd_file_acquire API. They manage their interest in
17 * the acquired object, and hence the object's reference count, via
18 * nfsd_file_get and nfsd_file_put. There are two varieties of nfsd_file
19 * object:
20 *
21 * * non-garbage-collected: When a consumer wants to precisely control
22 * the lifetime of a file's open state, it acquires a non-garbage-
23 * collected nfsd_file. The final nfsd_file_put releases the open
24 * state immediately.
25 *
26 * * garbage-collected: When a consumer does not control the lifetime
27 * of open state, it acquires a garbage-collected nfsd_file. The
28 * final nfsd_file_put allows the open state to linger for a period
29 * during which it may be re-used.
30 */
31
32 #include <linux/hash.h>
33 #include <linux/slab.h>
34 #include <linux/file.h>
35 #include <linux/pagemap.h>
36 #include <linux/sched.h>
37 #include <linux/list_lru.h>
38 #include <linux/fsnotify_backend.h>
39 #include <linux/fsnotify.h>
40 #include <linux/seq_file.h>
41 #include <linux/rhashtable.h>
42
43 #include "vfs.h"
44 #include "nfsd.h"
45 #include "nfsfh.h"
46 #include "netns.h"
47 #include "filecache.h"
48 #include "trace.h"
49
50 #define NFSD_LAUNDRETTE_DELAY (2 * HZ)
51
52 #define NFSD_FILE_CACHE_UP (0)
53
54 /* We only care about NFSD_MAY_READ/WRITE for this cache */
55 #define NFSD_FILE_MAY_MASK (NFSD_MAY_READ|NFSD_MAY_WRITE)
56
57 static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits);
58 static DEFINE_PER_CPU(unsigned long, nfsd_file_acquisitions);
59 static DEFINE_PER_CPU(unsigned long, nfsd_file_releases);
60 static DEFINE_PER_CPU(unsigned long, nfsd_file_total_age);
61 static DEFINE_PER_CPU(unsigned long, nfsd_file_evictions);
62
63 struct nfsd_fcache_disposal {
64 struct work_struct work;
65 spinlock_t lock;
66 struct list_head freeme;
67 };
68
69 static struct workqueue_struct *nfsd_filecache_wq __read_mostly;
70
71 static struct kmem_cache *nfsd_file_slab;
72 static struct kmem_cache *nfsd_file_mark_slab;
73 static struct list_lru nfsd_file_lru;
74 static unsigned long nfsd_file_flags;
75 static struct fsnotify_group *nfsd_file_fsnotify_group;
76 static struct delayed_work nfsd_filecache_laundrette;
77 static struct rhltable nfsd_file_rhltable
78 ____cacheline_aligned_in_smp;
79
80 static bool
nfsd_match_cred(const struct cred * c1,const struct cred * c2)81 nfsd_match_cred(const struct cred *c1, const struct cred *c2)
82 {
83 int i;
84
85 if (!uid_eq(c1->fsuid, c2->fsuid))
86 return false;
87 if (!gid_eq(c1->fsgid, c2->fsgid))
88 return false;
89 if (c1->group_info == NULL || c2->group_info == NULL)
90 return c1->group_info == c2->group_info;
91 if (c1->group_info->ngroups != c2->group_info->ngroups)
92 return false;
93 for (i = 0; i < c1->group_info->ngroups; i++) {
94 if (!gid_eq(c1->group_info->gid[i], c2->group_info->gid[i]))
95 return false;
96 }
97 return true;
98 }
99
100 static const struct rhashtable_params nfsd_file_rhash_params = {
101 .key_len = sizeof_field(struct nfsd_file, nf_inode),
102 .key_offset = offsetof(struct nfsd_file, nf_inode),
103 .head_offset = offsetof(struct nfsd_file, nf_rlist),
104
105 /*
106 * Start with a single page hash table to reduce resizing churn
107 * on light workloads.
108 */
109 .min_size = 256,
110 .automatic_shrinking = true,
111 };
112
113 static void
nfsd_file_schedule_laundrette(void)114 nfsd_file_schedule_laundrette(void)
115 {
116 if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags))
117 queue_delayed_work(system_wq, &nfsd_filecache_laundrette,
118 NFSD_LAUNDRETTE_DELAY);
119 }
120
121 static void
nfsd_file_slab_free(struct rcu_head * rcu)122 nfsd_file_slab_free(struct rcu_head *rcu)
123 {
124 struct nfsd_file *nf = container_of(rcu, struct nfsd_file, nf_rcu);
125
126 put_cred(nf->nf_cred);
127 kmem_cache_free(nfsd_file_slab, nf);
128 }
129
130 static void
nfsd_file_mark_free(struct fsnotify_mark * mark)131 nfsd_file_mark_free(struct fsnotify_mark *mark)
132 {
133 struct nfsd_file_mark *nfm = container_of(mark, struct nfsd_file_mark,
134 nfm_mark);
135
136 kmem_cache_free(nfsd_file_mark_slab, nfm);
137 }
138
139 static struct nfsd_file_mark *
nfsd_file_mark_get(struct nfsd_file_mark * nfm)140 nfsd_file_mark_get(struct nfsd_file_mark *nfm)
141 {
142 if (!refcount_inc_not_zero(&nfm->nfm_ref))
143 return NULL;
144 return nfm;
145 }
146
147 static void
nfsd_file_mark_put(struct nfsd_file_mark * nfm)148 nfsd_file_mark_put(struct nfsd_file_mark *nfm)
149 {
150 if (refcount_dec_and_test(&nfm->nfm_ref)) {
151 fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group);
152 fsnotify_put_mark(&nfm->nfm_mark);
153 }
154 }
155
156 static struct nfsd_file_mark *
nfsd_file_mark_find_or_create(struct nfsd_file * nf,struct inode * inode)157 nfsd_file_mark_find_or_create(struct nfsd_file *nf, struct inode *inode)
158 {
159 int err;
160 struct fsnotify_mark *mark;
161 struct nfsd_file_mark *nfm = NULL, *new;
162
163 do {
164 fsnotify_group_lock(nfsd_file_fsnotify_group);
165 mark = fsnotify_find_mark(&inode->i_fsnotify_marks,
166 nfsd_file_fsnotify_group);
167 if (mark) {
168 nfm = nfsd_file_mark_get(container_of(mark,
169 struct nfsd_file_mark,
170 nfm_mark));
171 fsnotify_group_unlock(nfsd_file_fsnotify_group);
172 if (nfm) {
173 fsnotify_put_mark(mark);
174 break;
175 }
176 /* Avoid soft lockup race with nfsd_file_mark_put() */
177 fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group);
178 fsnotify_put_mark(mark);
179 } else {
180 fsnotify_group_unlock(nfsd_file_fsnotify_group);
181 }
182
183 /* allocate a new nfm */
184 new = kmem_cache_alloc(nfsd_file_mark_slab, GFP_KERNEL);
185 if (!new)
186 return NULL;
187 fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group);
188 new->nfm_mark.mask = FS_ATTRIB|FS_DELETE_SELF;
189 refcount_set(&new->nfm_ref, 1);
190
191 err = fsnotify_add_inode_mark(&new->nfm_mark, inode, 0);
192
193 /*
194 * If the add was successful, then return the object.
195 * Otherwise, we need to put the reference we hold on the
196 * nfm_mark. The fsnotify code will take a reference and put
197 * it on failure, so we can't just free it directly. It's also
198 * not safe to call fsnotify_destroy_mark on it as the
199 * mark->group will be NULL. Thus, we can't let the nfm_ref
200 * counter drive the destruction at this point.
201 */
202 if (likely(!err))
203 nfm = new;
204 else
205 fsnotify_put_mark(&new->nfm_mark);
206 } while (unlikely(err == -EEXIST));
207
208 return nfm;
209 }
210
211 static struct nfsd_file *
nfsd_file_alloc(struct net * net,struct inode * inode,unsigned char need,bool want_gc)212 nfsd_file_alloc(struct net *net, struct inode *inode, unsigned char need,
213 bool want_gc)
214 {
215 struct nfsd_file *nf;
216
217 nf = kmem_cache_alloc(nfsd_file_slab, GFP_KERNEL);
218 if (unlikely(!nf))
219 return NULL;
220
221 INIT_LIST_HEAD(&nf->nf_lru);
222 INIT_LIST_HEAD(&nf->nf_gc);
223 nf->nf_birthtime = ktime_get();
224 nf->nf_file = NULL;
225 nf->nf_cred = get_current_cred();
226 nf->nf_net = net;
227 nf->nf_flags = want_gc ?
228 BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING) | BIT(NFSD_FILE_GC) :
229 BIT(NFSD_FILE_HASHED) | BIT(NFSD_FILE_PENDING);
230 nf->nf_inode = inode;
231 refcount_set(&nf->nf_ref, 1);
232 nf->nf_may = need;
233 nf->nf_mark = NULL;
234 return nf;
235 }
236
237 /**
238 * nfsd_file_check_write_error - check for writeback errors on a file
239 * @nf: nfsd_file to check for writeback errors
240 *
241 * Check whether a nfsd_file has an unseen error. Reset the write
242 * verifier if so.
243 */
244 static void
nfsd_file_check_write_error(struct nfsd_file * nf)245 nfsd_file_check_write_error(struct nfsd_file *nf)
246 {
247 struct file *file = nf->nf_file;
248
249 if ((file->f_mode & FMODE_WRITE) &&
250 filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err)))
251 nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
252 }
253
254 static void
nfsd_file_hash_remove(struct nfsd_file * nf)255 nfsd_file_hash_remove(struct nfsd_file *nf)
256 {
257 trace_nfsd_file_unhash(nf);
258 rhltable_remove(&nfsd_file_rhltable, &nf->nf_rlist,
259 nfsd_file_rhash_params);
260 }
261
262 static bool
nfsd_file_unhash(struct nfsd_file * nf)263 nfsd_file_unhash(struct nfsd_file *nf)
264 {
265 if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
266 nfsd_file_hash_remove(nf);
267 return true;
268 }
269 return false;
270 }
271
272 static void
nfsd_file_free(struct nfsd_file * nf)273 nfsd_file_free(struct nfsd_file *nf)
274 {
275 s64 age = ktime_to_ms(ktime_sub(ktime_get(), nf->nf_birthtime));
276
277 trace_nfsd_file_free(nf);
278
279 this_cpu_inc(nfsd_file_releases);
280 this_cpu_add(nfsd_file_total_age, age);
281
282 nfsd_file_unhash(nf);
283 if (nf->nf_mark)
284 nfsd_file_mark_put(nf->nf_mark);
285 if (nf->nf_file) {
286 nfsd_file_check_write_error(nf);
287 filp_close(nf->nf_file, NULL);
288 }
289
290 /*
291 * If this item is still linked via nf_lru, that's a bug.
292 * WARN and leak it to preserve system stability.
293 */
294 if (WARN_ON_ONCE(!list_empty(&nf->nf_lru)))
295 return;
296
297 call_rcu(&nf->nf_rcu, nfsd_file_slab_free);
298 }
299
300 static bool
nfsd_file_check_writeback(struct nfsd_file * nf)301 nfsd_file_check_writeback(struct nfsd_file *nf)
302 {
303 struct file *file = nf->nf_file;
304 struct address_space *mapping;
305
306 /* File not open for write? */
307 if (!(file->f_mode & FMODE_WRITE))
308 return false;
309
310 /*
311 * Some filesystems (e.g. NFS) flush all dirty data on close.
312 * On others, there is no need to wait for writeback.
313 */
314 if (!(file_inode(file)->i_sb->s_export_op->flags & EXPORT_OP_FLUSH_ON_CLOSE))
315 return false;
316
317 mapping = file->f_mapping;
318 return mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) ||
319 mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK);
320 }
321
322
nfsd_file_lru_add(struct nfsd_file * nf)323 static bool nfsd_file_lru_add(struct nfsd_file *nf)
324 {
325 set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
326 if (list_lru_add(&nfsd_file_lru, &nf->nf_lru)) {
327 trace_nfsd_file_lru_add(nf);
328 return true;
329 }
330 return false;
331 }
332
nfsd_file_lru_remove(struct nfsd_file * nf)333 static bool nfsd_file_lru_remove(struct nfsd_file *nf)
334 {
335 if (list_lru_del(&nfsd_file_lru, &nf->nf_lru)) {
336 trace_nfsd_file_lru_del(nf);
337 return true;
338 }
339 return false;
340 }
341
342 struct nfsd_file *
nfsd_file_get(struct nfsd_file * nf)343 nfsd_file_get(struct nfsd_file *nf)
344 {
345 if (nf && refcount_inc_not_zero(&nf->nf_ref))
346 return nf;
347 return NULL;
348 }
349
350 /**
351 * nfsd_file_put - put the reference to a nfsd_file
352 * @nf: nfsd_file of which to put the reference
353 *
354 * Put a reference to a nfsd_file. In the non-GC case, we just put the
355 * reference immediately. In the GC case, if the reference would be
356 * the last one, the put it on the LRU instead to be cleaned up later.
357 */
358 void
nfsd_file_put(struct nfsd_file * nf)359 nfsd_file_put(struct nfsd_file *nf)
360 {
361 might_sleep();
362 trace_nfsd_file_put(nf);
363
364 if (test_bit(NFSD_FILE_GC, &nf->nf_flags) &&
365 test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
366 /*
367 * If this is the last reference (nf_ref == 1), then try to
368 * transfer it to the LRU.
369 */
370 if (refcount_dec_not_one(&nf->nf_ref))
371 return;
372
373 /* Try to add it to the LRU. If that fails, decrement. */
374 if (nfsd_file_lru_add(nf)) {
375 /* If it's still hashed, we're done */
376 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
377 nfsd_file_schedule_laundrette();
378 return;
379 }
380
381 /*
382 * We're racing with unhashing, so try to remove it from
383 * the LRU. If removal fails, then someone else already
384 * has our reference.
385 */
386 if (!nfsd_file_lru_remove(nf))
387 return;
388 }
389 }
390 if (refcount_dec_and_test(&nf->nf_ref))
391 nfsd_file_free(nf);
392 }
393
394 static void
nfsd_file_dispose_list(struct list_head * dispose)395 nfsd_file_dispose_list(struct list_head *dispose)
396 {
397 struct nfsd_file *nf;
398
399 while (!list_empty(dispose)) {
400 nf = list_first_entry(dispose, struct nfsd_file, nf_gc);
401 list_del_init(&nf->nf_gc);
402 nfsd_file_free(nf);
403 }
404 }
405
406 /**
407 * nfsd_file_dispose_list_delayed - move list of dead files to net's freeme list
408 * @dispose: list of nfsd_files to be disposed
409 *
410 * Transfers each file to the "freeme" list for its nfsd_net, to eventually
411 * be disposed of by the per-net garbage collector.
412 */
413 static void
nfsd_file_dispose_list_delayed(struct list_head * dispose)414 nfsd_file_dispose_list_delayed(struct list_head *dispose)
415 {
416 while(!list_empty(dispose)) {
417 struct nfsd_file *nf = list_first_entry(dispose,
418 struct nfsd_file, nf_gc);
419 struct nfsd_net *nn = net_generic(nf->nf_net, nfsd_net_id);
420 struct nfsd_fcache_disposal *l = nn->fcache_disposal;
421
422 spin_lock(&l->lock);
423 list_move_tail(&nf->nf_gc, &l->freeme);
424 spin_unlock(&l->lock);
425 queue_work(nfsd_filecache_wq, &l->work);
426 }
427 }
428
429 /**
430 * nfsd_file_lru_cb - Examine an entry on the LRU list
431 * @item: LRU entry to examine
432 * @lru: controlling LRU
433 * @lock: LRU list lock (unused)
434 * @arg: dispose list
435 *
436 * Return values:
437 * %LRU_REMOVED: @item was removed from the LRU
438 * %LRU_ROTATE: @item is to be moved to the LRU tail
439 * %LRU_SKIP: @item cannot be evicted
440 */
441 static enum lru_status
nfsd_file_lru_cb(struct list_head * item,struct list_lru_one * lru,spinlock_t * lock,void * arg)442 nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru,
443 spinlock_t *lock, void *arg)
444 __releases(lock)
445 __acquires(lock)
446 {
447 struct list_head *head = arg;
448 struct nfsd_file *nf = list_entry(item, struct nfsd_file, nf_lru);
449
450 /* We should only be dealing with GC entries here */
451 WARN_ON_ONCE(!test_bit(NFSD_FILE_GC, &nf->nf_flags));
452
453 /*
454 * Don't throw out files that are still undergoing I/O or
455 * that have uncleared errors pending.
456 */
457 if (nfsd_file_check_writeback(nf)) {
458 trace_nfsd_file_gc_writeback(nf);
459 return LRU_SKIP;
460 }
461
462 /* If it was recently added to the list, skip it */
463 if (test_and_clear_bit(NFSD_FILE_REFERENCED, &nf->nf_flags)) {
464 trace_nfsd_file_gc_referenced(nf);
465 return LRU_ROTATE;
466 }
467
468 /*
469 * Put the reference held on behalf of the LRU. If it wasn't the last
470 * one, then just remove it from the LRU and ignore it.
471 */
472 if (!refcount_dec_and_test(&nf->nf_ref)) {
473 trace_nfsd_file_gc_in_use(nf);
474 list_lru_isolate(lru, &nf->nf_lru);
475 return LRU_REMOVED;
476 }
477
478 /* Refcount went to zero. Unhash it and queue it to the dispose list */
479 nfsd_file_unhash(nf);
480 list_lru_isolate(lru, &nf->nf_lru);
481 list_add(&nf->nf_gc, head);
482 this_cpu_inc(nfsd_file_evictions);
483 trace_nfsd_file_gc_disposed(nf);
484 return LRU_REMOVED;
485 }
486
487 static void
nfsd_file_gc(void)488 nfsd_file_gc(void)
489 {
490 LIST_HEAD(dispose);
491 unsigned long ret;
492
493 ret = list_lru_walk(&nfsd_file_lru, nfsd_file_lru_cb,
494 &dispose, list_lru_count(&nfsd_file_lru));
495 trace_nfsd_file_gc_removed(ret, list_lru_count(&nfsd_file_lru));
496 nfsd_file_dispose_list_delayed(&dispose);
497 }
498
499 static void
nfsd_file_gc_worker(struct work_struct * work)500 nfsd_file_gc_worker(struct work_struct *work)
501 {
502 nfsd_file_gc();
503 if (list_lru_count(&nfsd_file_lru))
504 nfsd_file_schedule_laundrette();
505 }
506
507 static unsigned long
nfsd_file_lru_count(struct shrinker * s,struct shrink_control * sc)508 nfsd_file_lru_count(struct shrinker *s, struct shrink_control *sc)
509 {
510 return list_lru_count(&nfsd_file_lru);
511 }
512
513 static unsigned long
nfsd_file_lru_scan(struct shrinker * s,struct shrink_control * sc)514 nfsd_file_lru_scan(struct shrinker *s, struct shrink_control *sc)
515 {
516 LIST_HEAD(dispose);
517 unsigned long ret;
518
519 ret = list_lru_shrink_walk(&nfsd_file_lru, sc,
520 nfsd_file_lru_cb, &dispose);
521 trace_nfsd_file_shrinker_removed(ret, list_lru_count(&nfsd_file_lru));
522 nfsd_file_dispose_list_delayed(&dispose);
523 return ret;
524 }
525
526 static struct shrinker nfsd_file_shrinker = {
527 .scan_objects = nfsd_file_lru_scan,
528 .count_objects = nfsd_file_lru_count,
529 .seeks = 1,
530 };
531
532 /**
533 * nfsd_file_cond_queue - conditionally unhash and queue a nfsd_file
534 * @nf: nfsd_file to attempt to queue
535 * @dispose: private list to queue successfully-put objects
536 *
537 * Unhash an nfsd_file, try to get a reference to it, and then put that
538 * reference. If it's the last reference, queue it to the dispose list.
539 */
540 static void
nfsd_file_cond_queue(struct nfsd_file * nf,struct list_head * dispose)541 nfsd_file_cond_queue(struct nfsd_file *nf, struct list_head *dispose)
542 __must_hold(RCU)
543 {
544 int decrement = 1;
545
546 /* If we raced with someone else unhashing, ignore it */
547 if (!nfsd_file_unhash(nf))
548 return;
549
550 /* If we can't get a reference, ignore it */
551 if (!nfsd_file_get(nf))
552 return;
553
554 /* Extra decrement if we remove from the LRU */
555 if (nfsd_file_lru_remove(nf))
556 ++decrement;
557
558 /* If refcount goes to 0, then put on the dispose list */
559 if (refcount_sub_and_test(decrement, &nf->nf_ref)) {
560 list_add(&nf->nf_gc, dispose);
561 trace_nfsd_file_closing(nf);
562 }
563 }
564
565 /**
566 * nfsd_file_queue_for_close: try to close out any open nfsd_files for an inode
567 * @inode: inode on which to close out nfsd_files
568 * @dispose: list on which to gather nfsd_files to close out
569 *
570 * An nfsd_file represents a struct file being held open on behalf of nfsd.
571 * An open file however can block other activity (such as leases), or cause
572 * undesirable behavior (e.g. spurious silly-renames when reexporting NFS).
573 *
574 * This function is intended to find open nfsd_files when this sort of
575 * conflicting access occurs and then attempt to close those files out.
576 *
577 * Populates the dispose list with entries that have already had their
578 * refcounts go to zero. The actual free of an nfsd_file can be expensive,
579 * so we leave it up to the caller whether it wants to wait or not.
580 */
581 static void
nfsd_file_queue_for_close(struct inode * inode,struct list_head * dispose)582 nfsd_file_queue_for_close(struct inode *inode, struct list_head *dispose)
583 {
584 struct rhlist_head *tmp, *list;
585 struct nfsd_file *nf;
586
587 rcu_read_lock();
588 list = rhltable_lookup(&nfsd_file_rhltable, &inode,
589 nfsd_file_rhash_params);
590 rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) {
591 if (!test_bit(NFSD_FILE_GC, &nf->nf_flags))
592 continue;
593 nfsd_file_cond_queue(nf, dispose);
594 }
595 rcu_read_unlock();
596 }
597
598 /**
599 * nfsd_file_close_inode - attempt a delayed close of a nfsd_file
600 * @inode: inode of the file to attempt to remove
601 *
602 * Close out any open nfsd_files that can be reaped for @inode. The
603 * actual freeing is deferred to the dispose_list_delayed infrastructure.
604 *
605 * This is used by the fsnotify callbacks and setlease notifier.
606 */
607 static void
nfsd_file_close_inode(struct inode * inode)608 nfsd_file_close_inode(struct inode *inode)
609 {
610 LIST_HEAD(dispose);
611
612 nfsd_file_queue_for_close(inode, &dispose);
613 nfsd_file_dispose_list_delayed(&dispose);
614 }
615
616 /**
617 * nfsd_file_close_inode_sync - attempt to forcibly close a nfsd_file
618 * @inode: inode of the file to attempt to remove
619 *
620 * Close out any open nfsd_files that can be reaped for @inode. The
621 * nfsd_files are closed out synchronously.
622 *
623 * This is called from nfsd_rename and nfsd_unlink to avoid silly-renames
624 * when reexporting NFS.
625 */
626 void
nfsd_file_close_inode_sync(struct inode * inode)627 nfsd_file_close_inode_sync(struct inode *inode)
628 {
629 struct nfsd_file *nf;
630 LIST_HEAD(dispose);
631
632 trace_nfsd_file_close(inode);
633
634 nfsd_file_queue_for_close(inode, &dispose);
635 while (!list_empty(&dispose)) {
636 nf = list_first_entry(&dispose, struct nfsd_file, nf_gc);
637 list_del_init(&nf->nf_gc);
638 nfsd_file_free(nf);
639 }
640 flush_delayed_fput();
641 }
642
643 /**
644 * nfsd_file_delayed_close - close unused nfsd_files
645 * @work: dummy
646 *
647 * Scrape the freeme list for this nfsd_net, and then dispose of them
648 * all.
649 */
650 static void
nfsd_file_delayed_close(struct work_struct * work)651 nfsd_file_delayed_close(struct work_struct *work)
652 {
653 LIST_HEAD(head);
654 struct nfsd_fcache_disposal *l = container_of(work,
655 struct nfsd_fcache_disposal, work);
656
657 spin_lock(&l->lock);
658 list_splice_init(&l->freeme, &head);
659 spin_unlock(&l->lock);
660
661 nfsd_file_dispose_list(&head);
662 }
663
664 static int
nfsd_file_lease_notifier_call(struct notifier_block * nb,unsigned long arg,void * data)665 nfsd_file_lease_notifier_call(struct notifier_block *nb, unsigned long arg,
666 void *data)
667 {
668 struct file_lock *fl = data;
669
670 /* Only close files for F_SETLEASE leases */
671 if (fl->fl_flags & FL_LEASE)
672 nfsd_file_close_inode(file_inode(fl->fl_file));
673 return 0;
674 }
675
676 static struct notifier_block nfsd_file_lease_notifier = {
677 .notifier_call = nfsd_file_lease_notifier_call,
678 };
679
680 static int
nfsd_file_fsnotify_handle_event(struct fsnotify_mark * mark,u32 mask,struct inode * inode,struct inode * dir,const struct qstr * name,u32 cookie)681 nfsd_file_fsnotify_handle_event(struct fsnotify_mark *mark, u32 mask,
682 struct inode *inode, struct inode *dir,
683 const struct qstr *name, u32 cookie)
684 {
685 if (WARN_ON_ONCE(!inode))
686 return 0;
687
688 trace_nfsd_file_fsnotify_handle_event(inode, mask);
689
690 /* Should be no marks on non-regular files */
691 if (!S_ISREG(inode->i_mode)) {
692 WARN_ON_ONCE(1);
693 return 0;
694 }
695
696 /* don't close files if this was not the last link */
697 if (mask & FS_ATTRIB) {
698 if (inode->i_nlink)
699 return 0;
700 }
701
702 nfsd_file_close_inode(inode);
703 return 0;
704 }
705
706
707 static const struct fsnotify_ops nfsd_file_fsnotify_ops = {
708 .handle_inode_event = nfsd_file_fsnotify_handle_event,
709 .free_mark = nfsd_file_mark_free,
710 };
711
712 int
nfsd_file_cache_init(void)713 nfsd_file_cache_init(void)
714 {
715 int ret;
716
717 lockdep_assert_held(&nfsd_mutex);
718 if (test_and_set_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1)
719 return 0;
720
721 ret = rhltable_init(&nfsd_file_rhltable, &nfsd_file_rhash_params);
722 if (ret)
723 goto out;
724
725 ret = -ENOMEM;
726 nfsd_filecache_wq = alloc_workqueue("nfsd_filecache", 0, 0);
727 if (!nfsd_filecache_wq)
728 goto out;
729
730 nfsd_file_slab = kmem_cache_create("nfsd_file",
731 sizeof(struct nfsd_file), 0, 0, NULL);
732 if (!nfsd_file_slab) {
733 pr_err("nfsd: unable to create nfsd_file_slab\n");
734 goto out_err;
735 }
736
737 nfsd_file_mark_slab = kmem_cache_create("nfsd_file_mark",
738 sizeof(struct nfsd_file_mark), 0, 0, NULL);
739 if (!nfsd_file_mark_slab) {
740 pr_err("nfsd: unable to create nfsd_file_mark_slab\n");
741 goto out_err;
742 }
743
744
745 ret = list_lru_init(&nfsd_file_lru);
746 if (ret) {
747 pr_err("nfsd: failed to init nfsd_file_lru: %d\n", ret);
748 goto out_err;
749 }
750
751 ret = register_shrinker(&nfsd_file_shrinker, "nfsd-filecache");
752 if (ret) {
753 pr_err("nfsd: failed to register nfsd_file_shrinker: %d\n", ret);
754 goto out_lru;
755 }
756
757 ret = lease_register_notifier(&nfsd_file_lease_notifier);
758 if (ret) {
759 pr_err("nfsd: unable to register lease notifier: %d\n", ret);
760 goto out_shrinker;
761 }
762
763 nfsd_file_fsnotify_group = fsnotify_alloc_group(&nfsd_file_fsnotify_ops,
764 FSNOTIFY_GROUP_NOFS);
765 if (IS_ERR(nfsd_file_fsnotify_group)) {
766 pr_err("nfsd: unable to create fsnotify group: %ld\n",
767 PTR_ERR(nfsd_file_fsnotify_group));
768 ret = PTR_ERR(nfsd_file_fsnotify_group);
769 nfsd_file_fsnotify_group = NULL;
770 goto out_notifier;
771 }
772
773 INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker);
774 out:
775 if (ret)
776 clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags);
777 return ret;
778 out_notifier:
779 lease_unregister_notifier(&nfsd_file_lease_notifier);
780 out_shrinker:
781 unregister_shrinker(&nfsd_file_shrinker);
782 out_lru:
783 list_lru_destroy(&nfsd_file_lru);
784 out_err:
785 kmem_cache_destroy(nfsd_file_slab);
786 nfsd_file_slab = NULL;
787 kmem_cache_destroy(nfsd_file_mark_slab);
788 nfsd_file_mark_slab = NULL;
789 destroy_workqueue(nfsd_filecache_wq);
790 nfsd_filecache_wq = NULL;
791 rhltable_destroy(&nfsd_file_rhltable);
792 goto out;
793 }
794
795 /**
796 * __nfsd_file_cache_purge: clean out the cache for shutdown
797 * @net: net-namespace to shut down the cache (may be NULL)
798 *
799 * Walk the nfsd_file cache and close out any that match @net. If @net is NULL,
800 * then close out everything. Called when an nfsd instance is being shut down,
801 * and when the exports table is flushed.
802 */
803 static void
__nfsd_file_cache_purge(struct net * net)804 __nfsd_file_cache_purge(struct net *net)
805 {
806 struct rhashtable_iter iter;
807 struct nfsd_file *nf;
808 LIST_HEAD(dispose);
809
810 rhltable_walk_enter(&nfsd_file_rhltable, &iter);
811 do {
812 rhashtable_walk_start(&iter);
813
814 nf = rhashtable_walk_next(&iter);
815 while (!IS_ERR_OR_NULL(nf)) {
816 if (!net || nf->nf_net == net)
817 nfsd_file_cond_queue(nf, &dispose);
818 nf = rhashtable_walk_next(&iter);
819 }
820
821 rhashtable_walk_stop(&iter);
822 } while (nf == ERR_PTR(-EAGAIN));
823 rhashtable_walk_exit(&iter);
824
825 nfsd_file_dispose_list(&dispose);
826 }
827
828 static struct nfsd_fcache_disposal *
nfsd_alloc_fcache_disposal(void)829 nfsd_alloc_fcache_disposal(void)
830 {
831 struct nfsd_fcache_disposal *l;
832
833 l = kmalloc(sizeof(*l), GFP_KERNEL);
834 if (!l)
835 return NULL;
836 INIT_WORK(&l->work, nfsd_file_delayed_close);
837 spin_lock_init(&l->lock);
838 INIT_LIST_HEAD(&l->freeme);
839 return l;
840 }
841
842 static void
nfsd_free_fcache_disposal(struct nfsd_fcache_disposal * l)843 nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)
844 {
845 cancel_work_sync(&l->work);
846 nfsd_file_dispose_list(&l->freeme);
847 kfree(l);
848 }
849
850 static void
nfsd_free_fcache_disposal_net(struct net * net)851 nfsd_free_fcache_disposal_net(struct net *net)
852 {
853 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
854 struct nfsd_fcache_disposal *l = nn->fcache_disposal;
855
856 nfsd_free_fcache_disposal(l);
857 }
858
859 int
nfsd_file_cache_start_net(struct net * net)860 nfsd_file_cache_start_net(struct net *net)
861 {
862 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
863
864 nn->fcache_disposal = nfsd_alloc_fcache_disposal();
865 return nn->fcache_disposal ? 0 : -ENOMEM;
866 }
867
868 /**
869 * nfsd_file_cache_purge - Remove all cache items associated with @net
870 * @net: target net namespace
871 *
872 */
873 void
nfsd_file_cache_purge(struct net * net)874 nfsd_file_cache_purge(struct net *net)
875 {
876 lockdep_assert_held(&nfsd_mutex);
877 if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1)
878 __nfsd_file_cache_purge(net);
879 }
880
881 void
nfsd_file_cache_shutdown_net(struct net * net)882 nfsd_file_cache_shutdown_net(struct net *net)
883 {
884 nfsd_file_cache_purge(net);
885 nfsd_free_fcache_disposal_net(net);
886 }
887
888 void
nfsd_file_cache_shutdown(void)889 nfsd_file_cache_shutdown(void)
890 {
891 int i;
892
893 lockdep_assert_held(&nfsd_mutex);
894 if (test_and_clear_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 0)
895 return;
896
897 lease_unregister_notifier(&nfsd_file_lease_notifier);
898 unregister_shrinker(&nfsd_file_shrinker);
899 /*
900 * make sure all callers of nfsd_file_lru_cb are done before
901 * calling nfsd_file_cache_purge
902 */
903 cancel_delayed_work_sync(&nfsd_filecache_laundrette);
904 __nfsd_file_cache_purge(NULL);
905 list_lru_destroy(&nfsd_file_lru);
906 rcu_barrier();
907 fsnotify_put_group(nfsd_file_fsnotify_group);
908 nfsd_file_fsnotify_group = NULL;
909 kmem_cache_destroy(nfsd_file_slab);
910 nfsd_file_slab = NULL;
911 fsnotify_wait_marks_destroyed();
912 kmem_cache_destroy(nfsd_file_mark_slab);
913 nfsd_file_mark_slab = NULL;
914 destroy_workqueue(nfsd_filecache_wq);
915 nfsd_filecache_wq = NULL;
916 rhltable_destroy(&nfsd_file_rhltable);
917
918 for_each_possible_cpu(i) {
919 per_cpu(nfsd_file_cache_hits, i) = 0;
920 per_cpu(nfsd_file_acquisitions, i) = 0;
921 per_cpu(nfsd_file_releases, i) = 0;
922 per_cpu(nfsd_file_total_age, i) = 0;
923 per_cpu(nfsd_file_evictions, i) = 0;
924 }
925 }
926
927 static struct nfsd_file *
nfsd_file_lookup_locked(const struct net * net,const struct cred * cred,struct inode * inode,unsigned char need,bool want_gc)928 nfsd_file_lookup_locked(const struct net *net, const struct cred *cred,
929 struct inode *inode, unsigned char need,
930 bool want_gc)
931 {
932 struct rhlist_head *tmp, *list;
933 struct nfsd_file *nf;
934
935 list = rhltable_lookup(&nfsd_file_rhltable, &inode,
936 nfsd_file_rhash_params);
937 rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist) {
938 if (nf->nf_may != need)
939 continue;
940 if (nf->nf_net != net)
941 continue;
942 if (!nfsd_match_cred(nf->nf_cred, cred))
943 continue;
944 if (test_bit(NFSD_FILE_GC, &nf->nf_flags) != want_gc)
945 continue;
946 if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0)
947 continue;
948
949 if (!nfsd_file_get(nf))
950 continue;
951 return nf;
952 }
953 return NULL;
954 }
955
956 /**
957 * nfsd_file_is_cached - are there any cached open files for this inode?
958 * @inode: inode to check
959 *
960 * The lookup matches inodes in all net namespaces and is atomic wrt
961 * nfsd_file_acquire().
962 *
963 * Return values:
964 * %true: filecache contains at least one file matching this inode
965 * %false: filecache contains no files matching this inode
966 */
967 bool
nfsd_file_is_cached(struct inode * inode)968 nfsd_file_is_cached(struct inode *inode)
969 {
970 struct rhlist_head *tmp, *list;
971 struct nfsd_file *nf;
972 bool ret = false;
973
974 rcu_read_lock();
975 list = rhltable_lookup(&nfsd_file_rhltable, &inode,
976 nfsd_file_rhash_params);
977 rhl_for_each_entry_rcu(nf, tmp, list, nf_rlist)
978 if (test_bit(NFSD_FILE_GC, &nf->nf_flags)) {
979 ret = true;
980 break;
981 }
982 rcu_read_unlock();
983
984 trace_nfsd_file_is_cached(inode, (int)ret);
985 return ret;
986 }
987
988 static __be32
nfsd_file_do_acquire(struct svc_rqst * rqstp,struct svc_fh * fhp,unsigned int may_flags,struct file * file,struct nfsd_file ** pnf,bool want_gc)989 nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
990 unsigned int may_flags, struct file *file,
991 struct nfsd_file **pnf, bool want_gc)
992 {
993 unsigned char need = may_flags & NFSD_FILE_MAY_MASK;
994 struct net *net = SVC_NET(rqstp);
995 struct nfsd_file *new, *nf;
996 bool stale_retry = true;
997 bool open_retry = true;
998 struct inode *inode;
999 __be32 status;
1000 int ret;
1001
1002 retry:
1003 status = fh_verify(rqstp, fhp, S_IFREG,
1004 may_flags|NFSD_MAY_OWNER_OVERRIDE);
1005 if (status != nfs_ok)
1006 return status;
1007 inode = d_inode(fhp->fh_dentry);
1008
1009 rcu_read_lock();
1010 nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc);
1011 rcu_read_unlock();
1012
1013 if (nf) {
1014 /*
1015 * If the nf is on the LRU then it holds an extra reference
1016 * that must be put if it's removed. It had better not be
1017 * the last one however, since we should hold another.
1018 */
1019 if (nfsd_file_lru_remove(nf))
1020 WARN_ON_ONCE(refcount_dec_and_test(&nf->nf_ref));
1021 goto wait_for_construction;
1022 }
1023
1024 new = nfsd_file_alloc(net, inode, need, want_gc);
1025 if (!new) {
1026 status = nfserr_jukebox;
1027 goto out;
1028 }
1029
1030 rcu_read_lock();
1031 spin_lock(&inode->i_lock);
1032 nf = nfsd_file_lookup_locked(net, current_cred(), inode, need, want_gc);
1033 if (unlikely(nf)) {
1034 spin_unlock(&inode->i_lock);
1035 rcu_read_unlock();
1036 nfsd_file_slab_free(&new->nf_rcu);
1037 goto wait_for_construction;
1038 }
1039 nf = new;
1040 ret = rhltable_insert(&nfsd_file_rhltable, &nf->nf_rlist,
1041 nfsd_file_rhash_params);
1042 spin_unlock(&inode->i_lock);
1043 rcu_read_unlock();
1044 if (likely(ret == 0))
1045 goto open_file;
1046
1047 trace_nfsd_file_insert_err(rqstp, inode, may_flags, ret);
1048 status = nfserr_jukebox;
1049 goto construction_err;
1050
1051 wait_for_construction:
1052 wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE);
1053
1054 /* Did construction of this file fail? */
1055 if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
1056 trace_nfsd_file_cons_err(rqstp, inode, may_flags, nf);
1057 if (!open_retry) {
1058 status = nfserr_jukebox;
1059 goto construction_err;
1060 }
1061 nfsd_file_put(nf);
1062 open_retry = false;
1063 fh_put(fhp);
1064 goto retry;
1065 }
1066 this_cpu_inc(nfsd_file_cache_hits);
1067
1068 status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags));
1069 if (status != nfs_ok) {
1070 nfsd_file_put(nf);
1071 nf = NULL;
1072 }
1073
1074 out:
1075 if (status == nfs_ok) {
1076 this_cpu_inc(nfsd_file_acquisitions);
1077 nfsd_file_check_write_error(nf);
1078 *pnf = nf;
1079 }
1080 trace_nfsd_file_acquire(rqstp, inode, may_flags, nf, status);
1081 return status;
1082
1083 open_file:
1084 trace_nfsd_file_alloc(nf);
1085 nf->nf_mark = nfsd_file_mark_find_or_create(nf, inode);
1086 if (nf->nf_mark) {
1087 if (file) {
1088 get_file(file);
1089 nf->nf_file = file;
1090 status = nfs_ok;
1091 trace_nfsd_file_opened(nf, status);
1092 } else {
1093 ret = nfsd_open_verified(rqstp, fhp, may_flags,
1094 &nf->nf_file);
1095 if (ret == -EOPENSTALE && stale_retry) {
1096 stale_retry = false;
1097 nfsd_file_unhash(nf);
1098 clear_and_wake_up_bit(NFSD_FILE_PENDING,
1099 &nf->nf_flags);
1100 if (refcount_dec_and_test(&nf->nf_ref))
1101 nfsd_file_free(nf);
1102 nf = NULL;
1103 fh_put(fhp);
1104 goto retry;
1105 }
1106 status = nfserrno(ret);
1107 trace_nfsd_file_open(nf, status);
1108 }
1109 } else
1110 status = nfserr_jukebox;
1111 /*
1112 * If construction failed, or we raced with a call to unlink()
1113 * then unhash.
1114 */
1115 if (status != nfs_ok || inode->i_nlink == 0)
1116 nfsd_file_unhash(nf);
1117 clear_and_wake_up_bit(NFSD_FILE_PENDING, &nf->nf_flags);
1118 if (status == nfs_ok)
1119 goto out;
1120
1121 construction_err:
1122 if (refcount_dec_and_test(&nf->nf_ref))
1123 nfsd_file_free(nf);
1124 nf = NULL;
1125 goto out;
1126 }
1127
1128 /**
1129 * nfsd_file_acquire_gc - Get a struct nfsd_file with an open file
1130 * @rqstp: the RPC transaction being executed
1131 * @fhp: the NFS filehandle of the file to be opened
1132 * @may_flags: NFSD_MAY_ settings for the file
1133 * @pnf: OUT: new or found "struct nfsd_file" object
1134 *
1135 * The nfsd_file object returned by this API is reference-counted
1136 * and garbage-collected. The object is retained for a few
1137 * seconds after the final nfsd_file_put() in case the caller
1138 * wants to re-use it.
1139 *
1140 * Return values:
1141 * %nfs_ok - @pnf points to an nfsd_file with its reference
1142 * count boosted.
1143 *
1144 * On error, an nfsstat value in network byte order is returned.
1145 */
1146 __be32
nfsd_file_acquire_gc(struct svc_rqst * rqstp,struct svc_fh * fhp,unsigned int may_flags,struct nfsd_file ** pnf)1147 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp,
1148 unsigned int may_flags, struct nfsd_file **pnf)
1149 {
1150 return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, true);
1151 }
1152
1153 /**
1154 * nfsd_file_acquire - Get a struct nfsd_file with an open file
1155 * @rqstp: the RPC transaction being executed
1156 * @fhp: the NFS filehandle of the file to be opened
1157 * @may_flags: NFSD_MAY_ settings for the file
1158 * @pnf: OUT: new or found "struct nfsd_file" object
1159 *
1160 * The nfsd_file_object returned by this API is reference-counted
1161 * but not garbage-collected. The object is unhashed after the
1162 * final nfsd_file_put().
1163 *
1164 * Return values:
1165 * %nfs_ok - @pnf points to an nfsd_file with its reference
1166 * count boosted.
1167 *
1168 * On error, an nfsstat value in network byte order is returned.
1169 */
1170 __be32
nfsd_file_acquire(struct svc_rqst * rqstp,struct svc_fh * fhp,unsigned int may_flags,struct nfsd_file ** pnf)1171 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
1172 unsigned int may_flags, struct nfsd_file **pnf)
1173 {
1174 return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, false);
1175 }
1176
1177 /**
1178 * nfsd_file_acquire_opened - Get a struct nfsd_file using existing open file
1179 * @rqstp: the RPC transaction being executed
1180 * @fhp: the NFS filehandle of the file just created
1181 * @may_flags: NFSD_MAY_ settings for the file
1182 * @file: cached, already-open file (may be NULL)
1183 * @pnf: OUT: new or found "struct nfsd_file" object
1184 *
1185 * Acquire a nfsd_file object that is not GC'ed. If one doesn't already exist,
1186 * and @file is non-NULL, use it to instantiate a new nfsd_file instead of
1187 * opening a new one.
1188 *
1189 * Return values:
1190 * %nfs_ok - @pnf points to an nfsd_file with its reference
1191 * count boosted.
1192 *
1193 * On error, an nfsstat value in network byte order is returned.
1194 */
1195 __be32
nfsd_file_acquire_opened(struct svc_rqst * rqstp,struct svc_fh * fhp,unsigned int may_flags,struct file * file,struct nfsd_file ** pnf)1196 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp,
1197 unsigned int may_flags, struct file *file,
1198 struct nfsd_file **pnf)
1199 {
1200 return nfsd_file_do_acquire(rqstp, fhp, may_flags, file, pnf, false);
1201 }
1202
1203 /*
1204 * Note that fields may be added, removed or reordered in the future. Programs
1205 * scraping this file for info should test the labels to ensure they're
1206 * getting the correct field.
1207 */
nfsd_file_cache_stats_show(struct seq_file * m,void * v)1208 int nfsd_file_cache_stats_show(struct seq_file *m, void *v)
1209 {
1210 unsigned long releases = 0, evictions = 0;
1211 unsigned long hits = 0, acquisitions = 0;
1212 unsigned int i, count = 0, buckets = 0;
1213 unsigned long lru = 0, total_age = 0;
1214
1215 /* Serialize with server shutdown */
1216 mutex_lock(&nfsd_mutex);
1217 if (test_bit(NFSD_FILE_CACHE_UP, &nfsd_file_flags) == 1) {
1218 struct bucket_table *tbl;
1219 struct rhashtable *ht;
1220
1221 lru = list_lru_count(&nfsd_file_lru);
1222
1223 rcu_read_lock();
1224 ht = &nfsd_file_rhltable.ht;
1225 count = atomic_read(&ht->nelems);
1226 tbl = rht_dereference_rcu(ht->tbl, ht);
1227 buckets = tbl->size;
1228 rcu_read_unlock();
1229 }
1230 mutex_unlock(&nfsd_mutex);
1231
1232 for_each_possible_cpu(i) {
1233 hits += per_cpu(nfsd_file_cache_hits, i);
1234 acquisitions += per_cpu(nfsd_file_acquisitions, i);
1235 releases += per_cpu(nfsd_file_releases, i);
1236 total_age += per_cpu(nfsd_file_total_age, i);
1237 evictions += per_cpu(nfsd_file_evictions, i);
1238 }
1239
1240 seq_printf(m, "total inodes: %u\n", count);
1241 seq_printf(m, "hash buckets: %u\n", buckets);
1242 seq_printf(m, "lru entries: %lu\n", lru);
1243 seq_printf(m, "cache hits: %lu\n", hits);
1244 seq_printf(m, "acquisitions: %lu\n", acquisitions);
1245 seq_printf(m, "releases: %lu\n", releases);
1246 seq_printf(m, "evictions: %lu\n", evictions);
1247 if (releases)
1248 seq_printf(m, "mean age (ms): %ld\n", total_age / releases);
1249 else
1250 seq_printf(m, "mean age (ms): -\n");
1251 return 0;
1252 }
1253