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