Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Sysctl operations for Coda filesystem | |
3 | * Original version: (C) 1996 P. Braam and M. Callahan | |
4 | * Rewritten for Linux 2.1. (C) 1997 Carnegie Mellon University | |
5 | * | |
6 | * Carnegie Mellon encourages users to contribute improvements to | |
7 | * the Coda project. Contact Peter Braam (coda@cs.cmu.edu). | |
8 | * | |
9 | * CODA operation statistics | |
10 | * (c) March, 1998 Zhanyong Wan <zhanyong.wan@yale.edu> | |
11 | * | |
12 | */ | |
13 | ||
1da177e4 LT |
14 | #include <linux/time.h> |
15 | #include <linux/mm.h> | |
16 | #include <linux/sysctl.h> | |
17 | #include <linux/proc_fs.h> | |
9bbf81e4 | 18 | #include <linux/seq_file.h> |
1da177e4 LT |
19 | #include <linux/slab.h> |
20 | #include <linux/stat.h> | |
21 | #include <linux/ctype.h> | |
22 | #include <linux/bitops.h> | |
23 | #include <asm/uaccess.h> | |
24 | #include <linux/utsname.h> | |
25 | #include <linux/module.h> | |
26 | ||
27 | #include <linux/coda.h> | |
28 | #include <linux/coda_linux.h> | |
29 | #include <linux/coda_fs_i.h> | |
30 | #include <linux/coda_psdev.h> | |
31 | #include <linux/coda_cache.h> | |
32 | #include <linux/coda_proc.h> | |
33 | ||
34 | static struct ctl_table_header *fs_table_header; | |
35 | ||
1da177e4 LT |
36 | #define CODA_TIMEOUT 3 /* timeout on upcalls to become intrble */ |
37 | #define CODA_HARD 5 /* mount type "hard" or "soft" */ | |
38 | #define CODA_VFS 6 /* vfs statistics */ | |
39 | #define CODA_CACHE_INV 9 /* cache invalidation statistics */ | |
40 | #define CODA_FAKE_STATFS 10 /* don't query venus for actual cache usage */ | |
41 | ||
42 | struct coda_vfs_stats coda_vfs_stat; | |
43 | static struct coda_cache_inv_stats coda_cache_inv_stat; | |
44 | ||
45 | static void reset_coda_vfs_stats( void ) | |
46 | { | |
47 | memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) ); | |
48 | } | |
49 | ||
50 | static void reset_coda_cache_inv_stats( void ) | |
51 | { | |
52 | memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) ); | |
53 | } | |
54 | ||
55 | static int do_reset_coda_vfs_stats( ctl_table * table, int write, | |
56 | struct file * filp, void __user * buffer, | |
57 | size_t * lenp, loff_t * ppos ) | |
58 | { | |
59 | if ( write ) { | |
60 | reset_coda_vfs_stats(); | |
61 | ||
62 | *ppos += *lenp; | |
63 | } else { | |
64 | *lenp = 0; | |
65 | } | |
66 | ||
67 | return 0; | |
68 | } | |
69 | ||
70 | static int do_reset_coda_cache_inv_stats( ctl_table * table, int write, | |
71 | struct file * filp, | |
72 | void __user * buffer, | |
73 | size_t * lenp, loff_t * ppos ) | |
74 | { | |
75 | if ( write ) { | |
76 | reset_coda_cache_inv_stats(); | |
77 | ||
78 | *ppos += *lenp; | |
79 | } else { | |
80 | *lenp = 0; | |
81 | } | |
82 | ||
83 | return 0; | |
84 | } | |
85 | ||
9bbf81e4 | 86 | static int proc_vfs_stats_show(struct seq_file *m, void *v) |
1da177e4 | 87 | { |
1da177e4 LT |
88 | struct coda_vfs_stats * ps = & coda_vfs_stat; |
89 | ||
9bbf81e4 | 90 | seq_printf(m, |
1da177e4 LT |
91 | "Coda VFS statistics\n" |
92 | "===================\n\n" | |
93 | "File Operations:\n" | |
94 | "\topen\t\t%9d\n" | |
95 | "\tflush\t\t%9d\n" | |
96 | "\trelease\t\t%9d\n" | |
97 | "\tfsync\t\t%9d\n\n" | |
98 | "Dir Operations:\n" | |
99 | "\treaddir\t\t%9d\n\n" | |
100 | "Inode Operations\n" | |
101 | "\tcreate\t\t%9d\n" | |
102 | "\tlookup\t\t%9d\n" | |
103 | "\tlink\t\t%9d\n" | |
104 | "\tunlink\t\t%9d\n" | |
105 | "\tsymlink\t\t%9d\n" | |
106 | "\tmkdir\t\t%9d\n" | |
107 | "\trmdir\t\t%9d\n" | |
108 | "\trename\t\t%9d\n" | |
109 | "\tpermission\t%9d\n", | |
110 | ||
111 | /* file operations */ | |
112 | ps->open, | |
113 | ps->flush, | |
114 | ps->release, | |
115 | ps->fsync, | |
116 | ||
117 | /* dir operations */ | |
118 | ps->readdir, | |
119 | ||
120 | /* inode operations */ | |
121 | ps->create, | |
122 | ps->lookup, | |
123 | ps->link, | |
124 | ps->unlink, | |
125 | ps->symlink, | |
126 | ps->mkdir, | |
127 | ps->rmdir, | |
128 | ps->rename, | |
129 | ps->permission); | |
9bbf81e4 | 130 | return 0; |
1da177e4 LT |
131 | } |
132 | ||
9bbf81e4 | 133 | static int proc_cache_inv_stats_show(struct seq_file *m, void *v) |
1da177e4 | 134 | { |
1da177e4 LT |
135 | struct coda_cache_inv_stats * ps = & coda_cache_inv_stat; |
136 | ||
9bbf81e4 | 137 | seq_printf(m, |
1da177e4 LT |
138 | "Coda cache invalidation statistics\n" |
139 | "==================================\n\n" | |
140 | "flush\t\t%9d\n" | |
141 | "purge user\t%9d\n" | |
142 | "zap_dir\t\t%9d\n" | |
143 | "zap_file\t%9d\n" | |
144 | "zap_vnode\t%9d\n" | |
145 | "purge_fid\t%9d\n" | |
146 | "replace\t\t%9d\n", | |
147 | ps->flush, | |
148 | ps->purge_user, | |
149 | ps->zap_dir, | |
150 | ps->zap_file, | |
151 | ps->zap_vnode, | |
152 | ps->purge_fid, | |
153 | ps->replace ); | |
9bbf81e4 AD |
154 | return 0; |
155 | } | |
1da177e4 | 156 | |
9bbf81e4 AD |
157 | static int proc_vfs_stats_open(struct inode *inode, struct file *file) |
158 | { | |
159 | return single_open(file, proc_vfs_stats_show, NULL); | |
160 | } | |
1da177e4 | 161 | |
9bbf81e4 AD |
162 | static int proc_cache_inv_stats_open(struct inode *inode, struct file *file) |
163 | { | |
164 | return single_open(file, proc_cache_inv_stats_show, NULL); | |
1da177e4 LT |
165 | } |
166 | ||
9bbf81e4 AD |
167 | static const struct file_operations proc_vfs_stats_fops = { |
168 | .owner = THIS_MODULE, | |
169 | .open = proc_vfs_stats_open, | |
170 | .read = seq_read, | |
171 | .llseek = seq_lseek, | |
172 | .release = single_release, | |
173 | }; | |
174 | ||
175 | static const struct file_operations proc_cache_inv_stats_fops = { | |
176 | .owner = THIS_MODULE, | |
177 | .open = proc_cache_inv_stats_open, | |
178 | .read = seq_read, | |
179 | .llseek = seq_lseek, | |
180 | .release = single_release, | |
181 | }; | |
182 | ||
1da177e4 | 183 | static ctl_table coda_table[] = { |
fd6065b4 EB |
184 | { |
185 | .ctl_name = CTL_UNNUMBERED, | |
186 | .procname = "timeout", | |
187 | .data = &coda_timeout, | |
188 | .maxlen = sizeof(int), | |
189 | .mode = 0644, | |
190 | .proc_handler = &proc_dointvec | |
191 | }, | |
192 | { | |
193 | .ctl_name = CTL_UNNUMBERED, | |
194 | .procname = "hard", | |
195 | .data = &coda_hard, | |
196 | .maxlen = sizeof(int), | |
197 | .mode = 0644, | |
198 | .proc_handler = &proc_dointvec | |
199 | }, | |
200 | { | |
201 | .ctl_name = CTL_UNNUMBERED, | |
202 | .procname = "vfs_stats", | |
203 | .data = NULL, | |
204 | .maxlen = 0, | |
205 | .mode = 0644, | |
206 | .proc_handler = &do_reset_coda_vfs_stats | |
207 | }, | |
208 | { | |
209 | .ctl_name = CTL_UNNUMBERED, | |
210 | .procname = "cache_inv_stats", | |
211 | .data = NULL, | |
212 | .maxlen = 0, | |
213 | .mode = 0644, | |
214 | .proc_handler = &do_reset_coda_cache_inv_stats | |
215 | }, | |
216 | { | |
217 | .ctl_name = CTL_UNNUMBERED, | |
218 | .procname = "fake_statfs", | |
219 | .data = &coda_fake_statfs, | |
220 | .maxlen = sizeof(int), | |
221 | .mode = 0600, | |
222 | .proc_handler = &proc_dointvec | |
223 | }, | |
224 | {} | |
1da177e4 LT |
225 | }; |
226 | ||
227 | static ctl_table fs_table[] = { | |
fd6065b4 EB |
228 | { |
229 | .ctl_name = CTL_UNNUMBERED, | |
230 | .procname = "coda", | |
231 | .mode = 0555, | |
232 | .child = coda_table | |
233 | }, | |
234 | {} | |
1da177e4 LT |
235 | }; |
236 | ||
237 | ||
238 | #ifdef CONFIG_PROC_FS | |
239 | ||
240 | /* | |
241 | target directory structure: | |
242 | /proc/fs (see linux/fs/proc/root.c) | |
243 | /proc/fs/coda | |
244 | /proc/fs/coda/{vfs_stats, | |
245 | ||
246 | */ | |
247 | ||
248 | static struct proc_dir_entry* proc_fs_coda; | |
249 | ||
250 | #endif | |
251 | ||
1da177e4 LT |
252 | void coda_sysctl_init(void) |
253 | { | |
254 | reset_coda_vfs_stats(); | |
255 | reset_coda_cache_inv_stats(); | |
256 | ||
257 | #ifdef CONFIG_PROC_FS | |
258 | proc_fs_coda = proc_mkdir("coda", proc_root_fs); | |
259 | if (proc_fs_coda) { | |
9bbf81e4 AD |
260 | struct proc_dir_entry *pde; |
261 | ||
1da177e4 | 262 | proc_fs_coda->owner = THIS_MODULE; |
9bbf81e4 AD |
263 | pde = create_proc_entry("vfs_stats", 0, proc_fs_coda); |
264 | if (pde) | |
265 | pde->proc_fops = &proc_vfs_stats_fops; | |
266 | pde = create_proc_entry("cache_inv_stats", 0, proc_fs_coda); | |
267 | if (pde) | |
268 | pde->proc_fops = &proc_cache_inv_stats_fops; | |
1da177e4 LT |
269 | } |
270 | #endif | |
271 | ||
272 | #ifdef CONFIG_SYSCTL | |
273 | if ( !fs_table_header ) | |
0b4d4147 | 274 | fs_table_header = register_sysctl_table(fs_table); |
1da177e4 LT |
275 | #endif |
276 | } | |
277 | ||
278 | void coda_sysctl_clean(void) | |
279 | { | |
280 | ||
281 | #ifdef CONFIG_SYSCTL | |
282 | if ( fs_table_header ) { | |
283 | unregister_sysctl_table(fs_table_header); | |
284 | fs_table_header = NULL; | |
285 | } | |
286 | #endif | |
287 | ||
288 | #ifdef CONFIG_PROC_FS | |
289 | remove_proc_entry("cache_inv_stats", proc_fs_coda); | |
290 | remove_proc_entry("vfs_stats", proc_fs_coda); | |
291 | remove_proc_entry("coda", proc_root_fs); | |
292 | #endif | |
293 | } |