diff options
Diffstat (limited to 'fs/cachefiles/proc.c')
-rw-r--r-- | fs/cachefiles/proc.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/fs/cachefiles/proc.c b/fs/cachefiles/proc.c new file mode 100644 index 000000000000..eccd33941199 --- /dev/null +++ b/fs/cachefiles/proc.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* CacheFiles 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 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 | #include <linux/module.h> | ||
13 | #include <linux/proc_fs.h> | ||
14 | #include <linux/seq_file.h> | ||
15 | #include "internal.h" | ||
16 | |||
17 | atomic_t cachefiles_lookup_histogram[HZ]; | ||
18 | atomic_t cachefiles_mkdir_histogram[HZ]; | ||
19 | atomic_t cachefiles_create_histogram[HZ]; | ||
20 | |||
21 | /* | ||
22 | * display the latency histogram | ||
23 | */ | ||
24 | static int cachefiles_histogram_show(struct seq_file *m, void *v) | ||
25 | { | ||
26 | unsigned long index; | ||
27 | unsigned x, y, z, t; | ||
28 | |||
29 | switch ((unsigned long) v) { | ||
30 | case 1: | ||
31 | seq_puts(m, "JIFS SECS LOOKUPS MKDIRS CREATES\n"); | ||
32 | return 0; | ||
33 | case 2: | ||
34 | seq_puts(m, "===== ===== ========= ========= =========\n"); | ||
35 | return 0; | ||
36 | default: | ||
37 | index = (unsigned long) v - 3; | ||
38 | x = atomic_read(&cachefiles_lookup_histogram[index]); | ||
39 | y = atomic_read(&cachefiles_mkdir_histogram[index]); | ||
40 | z = atomic_read(&cachefiles_create_histogram[index]); | ||
41 | if (x == 0 && y == 0 && z == 0) | ||
42 | return 0; | ||
43 | |||
44 | t = (index * 1000) / HZ; | ||
45 | |||
46 | seq_printf(m, "%4lu 0.%03u %9u %9u %9u\n", index, t, x, y, z); | ||
47 | return 0; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * set up the iterator to start reading from the first line | ||
53 | */ | ||
54 | static void *cachefiles_histogram_start(struct seq_file *m, loff_t *_pos) | ||
55 | { | ||
56 | if ((unsigned long long)*_pos >= HZ + 2) | ||
57 | return NULL; | ||
58 | if (*_pos == 0) | ||
59 | *_pos = 1; | ||
60 | return (void *)(unsigned long) *_pos; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * move to the next line | ||
65 | */ | ||
66 | static void *cachefiles_histogram_next(struct seq_file *m, void *v, loff_t *pos) | ||
67 | { | ||
68 | (*pos)++; | ||
69 | return (unsigned long long)*pos > HZ + 2 ? | ||
70 | NULL : (void *)(unsigned long) *pos; | ||
71 | } | ||
72 | |||
73 | /* | ||
74 | * clean up after reading | ||
75 | */ | ||
76 | static void cachefiles_histogram_stop(struct seq_file *m, void *v) | ||
77 | { | ||
78 | } | ||
79 | |||
80 | static const struct seq_operations cachefiles_histogram_ops = { | ||
81 | .start = cachefiles_histogram_start, | ||
82 | .stop = cachefiles_histogram_stop, | ||
83 | .next = cachefiles_histogram_next, | ||
84 | .show = cachefiles_histogram_show, | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * open "/proc/fs/cachefiles/XXX" which provide statistics summaries | ||
89 | */ | ||
90 | static int cachefiles_histogram_open(struct inode *inode, struct file *file) | ||
91 | { | ||
92 | return seq_open(file, &cachefiles_histogram_ops); | ||
93 | } | ||
94 | |||
95 | static const struct file_operations cachefiles_histogram_fops = { | ||
96 | .owner = THIS_MODULE, | ||
97 | .open = cachefiles_histogram_open, | ||
98 | .read = seq_read, | ||
99 | .llseek = seq_lseek, | ||
100 | .release = seq_release, | ||
101 | }; | ||
102 | |||
103 | /* | ||
104 | * initialise the /proc/fs/cachefiles/ directory | ||
105 | */ | ||
106 | int __init cachefiles_proc_init(void) | ||
107 | { | ||
108 | _enter(""); | ||
109 | |||
110 | if (!proc_mkdir("fs/cachefiles", NULL)) | ||
111 | goto error_dir; | ||
112 | |||
113 | if (!proc_create("fs/cachefiles/histogram", S_IFREG | 0444, NULL, | ||
114 | &cachefiles_histogram_fops)) | ||
115 | goto error_histogram; | ||
116 | |||
117 | _leave(" = 0"); | ||
118 | return 0; | ||
119 | |||
120 | error_histogram: | ||
121 | remove_proc_entry("fs/cachefiles", NULL); | ||
122 | error_dir: | ||
123 | _leave(" = -ENOMEM"); | ||
124 | return -ENOMEM; | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * clean up the /proc/fs/cachefiles/ directory | ||
129 | */ | ||
130 | void cachefiles_proc_cleanup(void) | ||
131 | { | ||
132 | remove_proc_entry("fs/cachefiles/histogram", NULL); | ||
133 | remove_proc_entry("fs/cachefiles", NULL); | ||
134 | } | ||