patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / fs / coda / sysctl.c
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
14 #include <linux/config.h>
15 #include <linux/time.h>
16 #include <linux/mm.h>
17 #include <linux/sysctl.h>
18 #include <linux/proc_fs.h>
19 #include <linux/slab.h>
20 #include <linux/stat.h>
21 #include <linux/ctype.h>
22 #include <asm/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
36 #define FS_CODA         1       /* Coda file system */
37
38 #define CODA_TIMEOUT    3       /* timeout on upcalls to become intrble */
39 #define CODA_HARD       5       /* mount type "hard" or "soft" */
40 #define CODA_VFS         6       /* vfs statistics */
41 #define CODA_CACHE_INV   9       /* cache invalidation statistics */
42 #define CODA_FAKE_STATFS 10      /* don't query venus for actual cache usage */
43
44 static ctl_table coda_table[] = {
45         {CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
46         {CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
47         {CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
48         {CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
49         {CODA_FAKE_STATFS, "fake_statfs", &coda_fake_statfs, sizeof(int), 0600, NULL, &proc_dointvec},
50         { 0 }
51 };
52
53 static ctl_table fs_table[] = {
54        {FS_CODA, "coda",    NULL, 0, 0555, coda_table},
55        {0}
56 };
57
58 struct coda_vfs_stats           coda_vfs_stat;
59 struct coda_cache_inv_stats     coda_cache_inv_stat;
60
61 void reset_coda_vfs_stats( void )
62 {
63         memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
64 }
65
66 void reset_coda_cache_inv_stats( void )
67 {
68         memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
69 }
70
71 int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
72                              void __user * buffer, size_t * lenp )
73 {
74         if ( write ) {
75                 reset_coda_vfs_stats();
76
77                 filp->f_pos += *lenp;
78         } else {
79                 *lenp = 0;
80         }
81
82         return 0;
83 }
84
85 int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
86                                    struct file * filp, void __user * buffer, 
87                                    size_t * lenp )
88 {
89         if ( write ) {
90                 reset_coda_cache_inv_stats();
91
92                 filp->f_pos += *lenp;
93         } else {
94                 *lenp = 0;
95         }
96   
97         return 0;
98 }
99
100 int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
101                              int length)
102 {
103         int len=0;
104         off_t begin;
105         struct coda_vfs_stats * ps = & coda_vfs_stat;
106   
107   /* this works as long as we are below 1024 characters! */
108         len += sprintf( buffer,
109                         "Coda VFS statistics\n"
110                         "===================\n\n"
111                         "File Operations:\n"
112                         "\topen\t\t%9d\n"
113                         "\tflush\t\t%9d\n"
114                         "\trelease\t\t%9d\n"
115                         "\tfsync\t\t%9d\n\n"
116                         "Dir Operations:\n"
117                         "\treaddir\t\t%9d\n\n"
118                         "Inode Operations\n"
119                         "\tcreate\t\t%9d\n"
120                         "\tlookup\t\t%9d\n"
121                         "\tlink\t\t%9d\n"
122                         "\tunlink\t\t%9d\n"
123                         "\tsymlink\t\t%9d\n"
124                         "\tmkdir\t\t%9d\n"
125                         "\trmdir\t\t%9d\n"
126                         "\trename\t\t%9d\n"
127                         "\tpermission\t%9d\n",
128
129                         /* file operations */
130                         ps->open,
131                         ps->flush,
132                         ps->release,
133                         ps->fsync,
134
135                         /* dir operations */
136                         ps->readdir,
137                   
138                         /* inode operations */
139                         ps->create,
140                         ps->lookup,
141                         ps->link,
142                         ps->unlink,
143                         ps->symlink,
144                         ps->mkdir,
145                         ps->rmdir,
146                         ps->rename,
147                         ps->permission); 
148
149         begin = offset;
150         *start = buffer + begin;
151         len -= begin;
152
153         if ( len > length )
154                 len = length;
155         if ( len < 0 )
156                 len = 0;
157
158         return len;
159 }
160
161 int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
162                                    int length)
163 {
164         int len=0;
165         off_t begin;
166         struct coda_cache_inv_stats * ps = & coda_cache_inv_stat;
167   
168         /* this works as long as we are below 1024 characters! */
169         len += sprintf( buffer,
170                         "Coda cache invalidation statistics\n"
171                         "==================================\n\n"
172                         "flush\t\t%9d\n"
173                         "purge user\t%9d\n"
174                         "zap_dir\t\t%9d\n"
175                         "zap_file\t%9d\n"
176                         "zap_vnode\t%9d\n"
177                         "purge_fid\t%9d\n"
178                         "replace\t\t%9d\n",
179                         ps->flush,
180                         ps->purge_user,
181                         ps->zap_dir,
182                         ps->zap_file,
183                         ps->zap_vnode,
184                         ps->purge_fid,
185                         ps->replace );
186   
187         begin = offset;
188         *start = buffer + begin;
189         len -= begin;
190
191         if ( len > length )
192                 len = length;
193         if ( len < 0 )
194                 len = 0;
195
196         return len;
197 }
198
199
200 #ifdef CONFIG_PROC_FS
201
202 /*
203  target directory structure:
204    /proc/fs  (see linux/fs/proc/root.c)
205    /proc/fs/coda
206    /proc/fs/coda/{vfs_stats,
207
208 */
209
210 struct proc_dir_entry* proc_fs_coda;
211
212 #endif
213
214 #define coda_proc_create(name,get_info) \
215         create_proc_info_entry(name, 0, proc_fs_coda, get_info)
216
217 void coda_sysctl_init(void)
218 {
219         reset_coda_vfs_stats();
220         reset_coda_cache_inv_stats();
221
222 #ifdef CONFIG_PROC_FS
223         proc_fs_coda = proc_mkdir("coda", proc_root_fs);
224         if (proc_fs_coda) {
225                 proc_fs_coda->owner = THIS_MODULE;
226                 coda_proc_create("vfs_stats", coda_vfs_stats_get_info);
227                 coda_proc_create("cache_inv_stats", coda_cache_inv_stats_get_info);
228         }
229 #endif
230
231 #ifdef CONFIG_SYSCTL
232         if ( !fs_table_header )
233                 fs_table_header = register_sysctl_table(fs_table, 0);
234 #endif 
235 }
236
237 void coda_sysctl_clean(void) 
238 {
239
240 #ifdef CONFIG_SYSCTL
241         if ( fs_table_header ) {
242                 unregister_sysctl_table(fs_table_header);
243                 fs_table_header = 0;
244         }
245 #endif
246
247 #ifdef CONFIG_PROC_FS
248         remove_proc_entry("cache_inv_stats", proc_fs_coda);
249         remove_proc_entry("vfs_stats", proc_fs_coda);
250         remove_proc_entry("coda", proc_root_fs);
251 #endif 
252 }