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