aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-04-03 11:42:37 -0400
committerDavid Howells <dhowells@redhat.com>2009-04-03 11:42:37 -0400
commit7394daa8c61dfda4baa687f133748fa0b599b017 (patch)
tree32d2c55ed60596918ec62ce6ecca186337bf4660 /fs/fscache
parent06b3db1b9bccdc8c2c743122a89745279e5ecc46 (diff)
FS-Cache: Add use of /proc and presentation of statistics
Make FS-Cache create its /proc interface and present various statistical information through it. Also provide the functions for updating this information. These features are enabled by: CONFIG_FSCACHE_PROC CONFIG_FSCACHE_STATS CONFIG_FSCACHE_HISTOGRAM The /proc directory for FS-Cache is also exported so that caching modules can add their own statistics there too. The FS-Cache module is loadable at this point, and the statistics files can be examined by userspace: cat /proc/fs/fscache/stats cat /proc/fs/fscache/histogram Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com> Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Tested-by: Daire Byrne <Daire.Byrne@framestore.com>
Diffstat (limited to 'fs/fscache')
-rw-r--r--fs/fscache/Kconfig34
-rw-r--r--fs/fscache/Makefile4
-rw-r--r--fs/fscache/histogram.c109
-rw-r--r--fs/fscache/internal.h127
-rw-r--r--fs/fscache/main.c7
-rw-r--r--fs/fscache/proc.c68
-rw-r--r--fs/fscache/stats.c212
7 files changed, 561 insertions, 0 deletions
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig
index 7c7bccd5eee4..9bbb8ce7bea0 100644
--- a/fs/fscache/Kconfig
+++ b/fs/fscache/Kconfig
@@ -11,6 +11,40 @@ config FSCACHE
11 11
12 See Documentation/filesystems/caching/fscache.txt for more information. 12 See Documentation/filesystems/caching/fscache.txt for more information.
13 13
14config FSCACHE_STATS
15 bool "Gather statistical information on local caching"
16 depends on FSCACHE && PROC_FS
17 help
18 This option causes statistical information to be gathered on local
19 caching and exported through file:
20
21 /proc/fs/fscache/stats
22
23 The gathering of statistics adds a certain amount of overhead to
24 execution as there are a quite a few stats gathered, and on a
25 multi-CPU system these may be on cachelines that keep bouncing
26 between CPUs. On the other hand, the stats are very useful for
27 debugging purposes. Saying 'Y' here is recommended.
28
29 See Documentation/filesystems/caching/fscache.txt for more information.
30
31config FSCACHE_HISTOGRAM
32 bool "Gather latency information on local caching"
33 depends on FSCACHE && PROC_FS
34 help
35 This option causes latency information to be gathered on local
36 caching and exported through file:
37
38 /proc/fs/fscache/histogram
39
40 The generation of this histogram adds a certain amount of overhead to
41 execution as there are a number of points at which data is gathered,
42 and on a multi-CPU system these may be on cachelines that keep
43 bouncing between CPUs. On the other hand, the histogram may be
44 useful for debugging purposes. Saying 'N' here is recommended.
45
46 See Documentation/filesystems/caching/fscache.txt for more information.
47
14config FSCACHE_DEBUG 48config FSCACHE_DEBUG
15 bool "Debug FS-Cache" 49 bool "Debug FS-Cache"
16 depends on FSCACHE 50 depends on FSCACHE
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile
index f8038b83e0ef..1384823a160c 100644
--- a/fs/fscache/Makefile
+++ b/fs/fscache/Makefile
@@ -5,4 +5,8 @@
5fscache-y := \ 5fscache-y := \
6 main.o 6 main.o
7 7
8fscache-$(CONFIG_PROC_FS) += proc.o
9fscache-$(CONFIG_FSCACHE_STATS) += stats.o
10fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
11
8obj-$(CONFIG_FSCACHE) := fscache.o 12obj-$(CONFIG_FSCACHE) := fscache.o
diff --git a/fs/fscache/histogram.c b/fs/fscache/histogram.c
new file mode 100644
index 000000000000..bad496748a59
--- /dev/null
+++ b/fs/fscache/histogram.c
@@ -0,0 +1,109 @@
1/* FS-Cache latency histogram
2 *
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#define FSCACHE_DEBUG_LEVEL THREAD
13#include <linux/module.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
16#include "internal.h"
17
18atomic_t fscache_obj_instantiate_histogram[HZ];
19atomic_t fscache_objs_histogram[HZ];
20atomic_t fscache_ops_histogram[HZ];
21atomic_t fscache_retrieval_delay_histogram[HZ];
22atomic_t fscache_retrieval_histogram[HZ];
23
24/*
25 * display the time-taken histogram
26 */
27static int fscache_histogram_show(struct seq_file *m, void *v)
28{
29 unsigned long index;
30 unsigned n[5], t;
31
32 switch ((unsigned long) v) {
33 case 1:
34 seq_puts(m, "JIFS SECS OBJ INST OP RUNS OBJ RUNS "
35 " RETRV DLY RETRIEVLS\n");
36 return 0;
37 case 2:
38 seq_puts(m, "===== ===== ========= ========= ========="
39 " ========= =========\n");
40 return 0;
41 default:
42 index = (unsigned long) v - 3;
43 n[0] = atomic_read(&fscache_obj_instantiate_histogram[index]);
44 n[1] = atomic_read(&fscache_ops_histogram[index]);
45 n[2] = atomic_read(&fscache_objs_histogram[index]);
46 n[3] = atomic_read(&fscache_retrieval_delay_histogram[index]);
47 n[4] = atomic_read(&fscache_retrieval_histogram[index]);
48 if (!(n[0] | n[1] | n[2] | n[3] | n[4]))
49 return 0;
50
51 t = (index * 1000) / HZ;
52
53 seq_printf(m, "%4lu 0.%03u %9u %9u %9u %9u %9u\n",
54 index, t, n[0], n[1], n[2], n[3], n[4]);
55 return 0;
56 }
57}
58
59/*
60 * set up the iterator to start reading from the first line
61 */
62static void *fscache_histogram_start(struct seq_file *m, loff_t *_pos)
63{
64 if ((unsigned long long)*_pos >= HZ + 2)
65 return NULL;
66 if (*_pos == 0)
67 *_pos = 1;
68 return (void *)(unsigned long) *_pos;
69}
70
71/*
72 * move to the next line
73 */
74static void *fscache_histogram_next(struct seq_file *m, void *v, loff_t *pos)
75{
76 (*pos)++;
77 return (unsigned long long)*pos > HZ + 2 ?
78 NULL : (void *)(unsigned long) *pos;
79}
80
81/*
82 * clean up after reading
83 */
84static void fscache_histogram_stop(struct seq_file *m, void *v)
85{
86}
87
88static const struct seq_operations fscache_histogram_ops = {
89 .start = fscache_histogram_start,
90 .stop = fscache_histogram_stop,
91 .next = fscache_histogram_next,
92 .show = fscache_histogram_show,
93};
94
95/*
96 * open "/proc/fs/fscache/histogram" to provide latency data
97 */
98static int fscache_histogram_open(struct inode *inode, struct file *file)
99{
100 return seq_open(file, &fscache_histogram_ops);
101}
102
103const struct file_operations fscache_histogram_fops = {
104 .owner = THIS_MODULE,
105 .open = fscache_histogram_open,
106 .read = seq_read,
107 .llseek = seq_lseek,
108 .release = seq_release,
109};
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 95dc92da7152..16f9f1f46e4d 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -28,6 +28,30 @@
28#define FSCACHE_MAX_THREADS 32 28#define FSCACHE_MAX_THREADS 32
29 29
30/* 30/*
31 * fsc-histogram.c
32 */
33#ifdef CONFIG_FSCACHE_HISTOGRAM
34extern atomic_t fscache_obj_instantiate_histogram[HZ];
35extern atomic_t fscache_objs_histogram[HZ];
36extern atomic_t fscache_ops_histogram[HZ];
37extern atomic_t fscache_retrieval_delay_histogram[HZ];
38extern atomic_t fscache_retrieval_histogram[HZ];
39
40static inline void fscache_hist(atomic_t histogram[], unsigned long start_jif)
41{
42 unsigned long jif = jiffies - start_jif;
43 if (jif >= HZ)
44 jif = HZ - 1;
45 atomic_inc(&histogram[jif]);
46}
47
48extern const struct file_operations fscache_histogram_fops;
49
50#else
51#define fscache_hist(hist, start_jif) do {} while (0)
52#endif
53
54/*
31 * fsc-main.c 55 * fsc-main.c
32 */ 56 */
33extern unsigned fscache_defer_lookup; 57extern unsigned fscache_defer_lookup;
@@ -35,6 +59,109 @@ extern unsigned fscache_defer_create;
35extern unsigned fscache_debug; 59extern unsigned fscache_debug;
36extern struct kobject *fscache_root; 60extern struct kobject *fscache_root;
37 61
62/*
63 * fsc-proc.c
64 */
65#ifdef CONFIG_PROC_FS
66extern int __init fscache_proc_init(void);
67extern void fscache_proc_cleanup(void);
68#else
69#define fscache_proc_init() (0)
70#define fscache_proc_cleanup() do {} while (0)
71#endif
72
73/*
74 * fsc-stats.c
75 */
76#ifdef CONFIG_FSCACHE_STATS
77extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS];
78extern atomic_t fscache_n_objs_processed[FSCACHE_MAX_THREADS];
79
80extern atomic_t fscache_n_op_pend;
81extern atomic_t fscache_n_op_run;
82extern atomic_t fscache_n_op_enqueue;
83extern atomic_t fscache_n_op_deferred_release;
84extern atomic_t fscache_n_op_release;
85extern atomic_t fscache_n_op_gc;
86
87extern atomic_t fscache_n_attr_changed;
88extern atomic_t fscache_n_attr_changed_ok;
89extern atomic_t fscache_n_attr_changed_nobufs;
90extern atomic_t fscache_n_attr_changed_nomem;
91extern atomic_t fscache_n_attr_changed_calls;
92
93extern atomic_t fscache_n_allocs;
94extern atomic_t fscache_n_allocs_ok;
95extern atomic_t fscache_n_allocs_wait;
96extern atomic_t fscache_n_allocs_nobufs;
97extern atomic_t fscache_n_alloc_ops;
98extern atomic_t fscache_n_alloc_op_waits;
99
100extern atomic_t fscache_n_retrievals;
101extern atomic_t fscache_n_retrievals_ok;
102extern atomic_t fscache_n_retrievals_wait;
103extern atomic_t fscache_n_retrievals_nodata;
104extern atomic_t fscache_n_retrievals_nobufs;
105extern atomic_t fscache_n_retrievals_intr;
106extern atomic_t fscache_n_retrievals_nomem;
107extern atomic_t fscache_n_retrieval_ops;
108extern atomic_t fscache_n_retrieval_op_waits;
109
110extern atomic_t fscache_n_stores;
111extern atomic_t fscache_n_stores_ok;
112extern atomic_t fscache_n_stores_again;
113extern atomic_t fscache_n_stores_nobufs;
114extern atomic_t fscache_n_stores_oom;
115extern atomic_t fscache_n_store_ops;
116extern atomic_t fscache_n_store_calls;
117
118extern atomic_t fscache_n_marks;
119extern atomic_t fscache_n_uncaches;
120
121extern atomic_t fscache_n_acquires;
122extern atomic_t fscache_n_acquires_null;
123extern atomic_t fscache_n_acquires_no_cache;
124extern atomic_t fscache_n_acquires_ok;
125extern atomic_t fscache_n_acquires_nobufs;
126extern atomic_t fscache_n_acquires_oom;
127
128extern atomic_t fscache_n_updates;
129extern atomic_t fscache_n_updates_null;
130extern atomic_t fscache_n_updates_run;
131
132extern atomic_t fscache_n_relinquishes;
133extern atomic_t fscache_n_relinquishes_null;
134extern atomic_t fscache_n_relinquishes_waitcrt;
135
136extern atomic_t fscache_n_cookie_index;
137extern atomic_t fscache_n_cookie_data;
138extern atomic_t fscache_n_cookie_special;
139
140extern atomic_t fscache_n_object_alloc;
141extern atomic_t fscache_n_object_no_alloc;
142extern atomic_t fscache_n_object_lookups;
143extern atomic_t fscache_n_object_lookups_negative;
144extern atomic_t fscache_n_object_lookups_positive;
145extern atomic_t fscache_n_object_created;
146extern atomic_t fscache_n_object_avail;
147extern atomic_t fscache_n_object_dead;
148
149extern atomic_t fscache_n_checkaux_none;
150extern atomic_t fscache_n_checkaux_okay;
151extern atomic_t fscache_n_checkaux_update;
152extern atomic_t fscache_n_checkaux_obsolete;
153
154static inline void fscache_stat(atomic_t *stat)
155{
156 atomic_inc(stat);
157}
158
159extern const struct file_operations fscache_stats_fops;
160#else
161
162#define fscache_stat(stat) do {} while (0)
163#endif
164
38/*****************************************************************************/ 165/*****************************************************************************/
39/* 166/*
40 * debug tracing 167 * debug tracing
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index 76f7c69079c0..7c734b7fb18e 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -52,9 +52,15 @@ static int __init fscache_init(void)
52 if (ret < 0) 52 if (ret < 0)
53 goto error_slow_work; 53 goto error_slow_work;
54 54
55 ret = fscache_proc_init();
56 if (ret < 0)
57 goto error_proc;
58
55 printk(KERN_NOTICE "FS-Cache: Loaded\n"); 59 printk(KERN_NOTICE "FS-Cache: Loaded\n");
56 return 0; 60 return 0;
57 61
62error_proc:
63 slow_work_unregister_user();
58error_slow_work: 64error_slow_work:
59 return ret; 65 return ret;
60} 66}
@@ -68,6 +74,7 @@ static void __exit fscache_exit(void)
68{ 74{
69 _enter(""); 75 _enter("");
70 76
77 fscache_proc_cleanup();
71 slow_work_unregister_user(); 78 slow_work_unregister_user();
72 printk(KERN_NOTICE "FS-Cache: Unloaded\n"); 79 printk(KERN_NOTICE "FS-Cache: Unloaded\n");
73} 80}
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c
new file mode 100644
index 000000000000..beeab44bc31a
--- /dev/null
+++ b/fs/fscache/proc.c
@@ -0,0 +1,68 @@
1/* FS-Cache statistics viewing interface
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#define FSCACHE_DEBUG_LEVEL OPERATION
13#include <linux/module.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
16#include "internal.h"
17
18/*
19 * initialise the /proc/fs/fscache/ directory
20 */
21int __init fscache_proc_init(void)
22{
23 _enter("");
24
25 if (!proc_mkdir("fs/fscache", NULL))
26 goto error_dir;
27
28#ifdef CONFIG_FSCACHE_STATS
29 if (!proc_create("fs/fscache/stats", S_IFREG | 0444, NULL,
30 &fscache_stats_fops))
31 goto error_stats;
32#endif
33
34#ifdef CONFIG_FSCACHE_HISTOGRAM
35 if (!proc_create("fs/fscache/histogram", S_IFREG | 0444, NULL,
36 &fscache_histogram_fops))
37 goto error_histogram;
38#endif
39
40 _leave(" = 0");
41 return 0;
42
43#ifdef CONFIG_FSCACHE_HISTOGRAM
44error_histogram:
45#endif
46#ifdef CONFIG_FSCACHE_STATS
47 remove_proc_entry("fs/fscache/stats", NULL);
48error_stats:
49#endif
50 remove_proc_entry("fs/fscache", NULL);
51error_dir:
52 _leave(" = -ENOMEM");
53 return -ENOMEM;
54}
55
56/*
57 * clean up the /proc/fs/fscache/ directory
58 */
59void fscache_proc_cleanup(void)
60{
61#ifdef CONFIG_FSCACHE_HISTOGRAM
62 remove_proc_entry("fs/fscache/histogram", NULL);
63#endif
64#ifdef CONFIG_FSCACHE_STATS
65 remove_proc_entry("fs/fscache/stats", NULL);
66#endif
67 remove_proc_entry("fs/fscache", NULL);
68}
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c
new file mode 100644
index 000000000000..65deb99e756b
--- /dev/null
+++ b/fs/fscache/stats.c
@@ -0,0 +1,212 @@
1/* FS-Cache statistics
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#define FSCACHE_DEBUG_LEVEL THREAD
13#include <linux/module.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
16#include "internal.h"
17
18/*
19 * operation counters
20 */
21atomic_t fscache_n_op_pend;
22atomic_t fscache_n_op_run;
23atomic_t fscache_n_op_enqueue;
24atomic_t fscache_n_op_requeue;
25atomic_t fscache_n_op_deferred_release;
26atomic_t fscache_n_op_release;
27atomic_t fscache_n_op_gc;
28
29atomic_t fscache_n_attr_changed;
30atomic_t fscache_n_attr_changed_ok;
31atomic_t fscache_n_attr_changed_nobufs;
32atomic_t fscache_n_attr_changed_nomem;
33atomic_t fscache_n_attr_changed_calls;
34
35atomic_t fscache_n_allocs;
36atomic_t fscache_n_allocs_ok;
37atomic_t fscache_n_allocs_wait;
38atomic_t fscache_n_allocs_nobufs;
39atomic_t fscache_n_alloc_ops;
40atomic_t fscache_n_alloc_op_waits;
41
42atomic_t fscache_n_retrievals;
43atomic_t fscache_n_retrievals_ok;
44atomic_t fscache_n_retrievals_wait;
45atomic_t fscache_n_retrievals_nodata;
46atomic_t fscache_n_retrievals_nobufs;
47atomic_t fscache_n_retrievals_intr;
48atomic_t fscache_n_retrievals_nomem;
49atomic_t fscache_n_retrieval_ops;
50atomic_t fscache_n_retrieval_op_waits;
51
52atomic_t fscache_n_stores;
53atomic_t fscache_n_stores_ok;
54atomic_t fscache_n_stores_again;
55atomic_t fscache_n_stores_nobufs;
56atomic_t fscache_n_stores_oom;
57atomic_t fscache_n_store_ops;
58atomic_t fscache_n_store_calls;
59
60atomic_t fscache_n_marks;
61atomic_t fscache_n_uncaches;
62
63atomic_t fscache_n_acquires;
64atomic_t fscache_n_acquires_null;
65atomic_t fscache_n_acquires_no_cache;
66atomic_t fscache_n_acquires_ok;
67atomic_t fscache_n_acquires_nobufs;
68atomic_t fscache_n_acquires_oom;
69
70atomic_t fscache_n_updates;
71atomic_t fscache_n_updates_null;
72atomic_t fscache_n_updates_run;
73
74atomic_t fscache_n_relinquishes;
75atomic_t fscache_n_relinquishes_null;
76atomic_t fscache_n_relinquishes_waitcrt;
77
78atomic_t fscache_n_cookie_index;
79atomic_t fscache_n_cookie_data;
80atomic_t fscache_n_cookie_special;
81
82atomic_t fscache_n_object_alloc;
83atomic_t fscache_n_object_no_alloc;
84atomic_t fscache_n_object_lookups;
85atomic_t fscache_n_object_lookups_negative;
86atomic_t fscache_n_object_lookups_positive;
87atomic_t fscache_n_object_created;
88atomic_t fscache_n_object_avail;
89atomic_t fscache_n_object_dead;
90
91atomic_t fscache_n_checkaux_none;
92atomic_t fscache_n_checkaux_okay;
93atomic_t fscache_n_checkaux_update;
94atomic_t fscache_n_checkaux_obsolete;
95
96/*
97 * display the general statistics
98 */
99static int fscache_stats_show(struct seq_file *m, void *v)
100{
101 seq_puts(m, "FS-Cache statistics\n");
102
103 seq_printf(m, "Cookies: idx=%u dat=%u spc=%u\n",
104 atomic_read(&fscache_n_cookie_index),
105 atomic_read(&fscache_n_cookie_data),
106 atomic_read(&fscache_n_cookie_special));
107
108 seq_printf(m, "Objects: alc=%u nal=%u avl=%u ded=%u\n",
109 atomic_read(&fscache_n_object_alloc),
110 atomic_read(&fscache_n_object_no_alloc),
111 atomic_read(&fscache_n_object_avail),
112 atomic_read(&fscache_n_object_dead));
113 seq_printf(m, "ChkAux : non=%u ok=%u upd=%u obs=%u\n",
114 atomic_read(&fscache_n_checkaux_none),
115 atomic_read(&fscache_n_checkaux_okay),
116 atomic_read(&fscache_n_checkaux_update),
117 atomic_read(&fscache_n_checkaux_obsolete));
118
119 seq_printf(m, "Pages : mrk=%u unc=%u\n",
120 atomic_read(&fscache_n_marks),
121 atomic_read(&fscache_n_uncaches));
122
123 seq_printf(m, "Acquire: n=%u nul=%u noc=%u ok=%u nbf=%u"
124 " oom=%u\n",
125 atomic_read(&fscache_n_acquires),
126 atomic_read(&fscache_n_acquires_null),
127 atomic_read(&fscache_n_acquires_no_cache),
128 atomic_read(&fscache_n_acquires_ok),
129 atomic_read(&fscache_n_acquires_nobufs),
130 atomic_read(&fscache_n_acquires_oom));
131
132 seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
133 atomic_read(&fscache_n_object_lookups),
134 atomic_read(&fscache_n_object_lookups_negative),
135 atomic_read(&fscache_n_object_lookups_positive),
136 atomic_read(&fscache_n_object_created));
137
138 seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
139 atomic_read(&fscache_n_updates),
140 atomic_read(&fscache_n_updates_null),
141 atomic_read(&fscache_n_updates_run));
142
143 seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
144 atomic_read(&fscache_n_relinquishes),
145 atomic_read(&fscache_n_relinquishes_null),
146 atomic_read(&fscache_n_relinquishes_waitcrt));
147
148 seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
149 atomic_read(&fscache_n_attr_changed),
150 atomic_read(&fscache_n_attr_changed_ok),
151 atomic_read(&fscache_n_attr_changed_nobufs),
152 atomic_read(&fscache_n_attr_changed_nomem),
153 atomic_read(&fscache_n_attr_changed_calls));
154
155 seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
156 atomic_read(&fscache_n_allocs),
157 atomic_read(&fscache_n_allocs_ok),
158 atomic_read(&fscache_n_allocs_wait),
159 atomic_read(&fscache_n_allocs_nobufs));
160 seq_printf(m, "Allocs : ops=%u owt=%u\n",
161 atomic_read(&fscache_n_alloc_ops),
162 atomic_read(&fscache_n_alloc_op_waits));
163
164 seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
165 " int=%u oom=%u\n",
166 atomic_read(&fscache_n_retrievals),
167 atomic_read(&fscache_n_retrievals_ok),
168 atomic_read(&fscache_n_retrievals_wait),
169 atomic_read(&fscache_n_retrievals_nodata),
170 atomic_read(&fscache_n_retrievals_nobufs),
171 atomic_read(&fscache_n_retrievals_intr),
172 atomic_read(&fscache_n_retrievals_nomem));
173 seq_printf(m, "Retrvls: ops=%u owt=%u\n",
174 atomic_read(&fscache_n_retrieval_ops),
175 atomic_read(&fscache_n_retrieval_op_waits));
176
177 seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
178 atomic_read(&fscache_n_stores),
179 atomic_read(&fscache_n_stores_ok),
180 atomic_read(&fscache_n_stores_again),
181 atomic_read(&fscache_n_stores_nobufs),
182 atomic_read(&fscache_n_stores_oom));
183 seq_printf(m, "Stores : ops=%u run=%u\n",
184 atomic_read(&fscache_n_store_ops),
185 atomic_read(&fscache_n_store_calls));
186
187 seq_printf(m, "Ops : pend=%u run=%u enq=%u\n",
188 atomic_read(&fscache_n_op_pend),
189 atomic_read(&fscache_n_op_run),
190 atomic_read(&fscache_n_op_enqueue));
191 seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n",
192 atomic_read(&fscache_n_op_deferred_release),
193 atomic_read(&fscache_n_op_release),
194 atomic_read(&fscache_n_op_gc));
195 return 0;
196}
197
198/*
199 * open "/proc/fs/fscache/stats" allowing provision of a statistical summary
200 */
201static int fscache_stats_open(struct inode *inode, struct file *file)
202{
203 return single_open(file, fscache_stats_show, NULL);
204}
205
206const struct file_operations fscache_stats_fops = {
207 .owner = THIS_MODULE,
208 .open = fscache_stats_open,
209 .read = seq_read,
210 .llseek = seq_lseek,
211 .release = seq_release,
212};