at v2.6.24-rc1 157 lines 3.1 kB view raw
1/* 2 * linux/net/sunrpc/sysctl.c 3 * 4 * Sysctl interface to sunrpc module. 5 * 6 * I would prefer to register the sunrpc table below sys/net, but that's 7 * impossible at the moment. 8 */ 9 10#include <linux/types.h> 11#include <linux/linkage.h> 12#include <linux/ctype.h> 13#include <linux/fs.h> 14#include <linux/sysctl.h> 15#include <linux/module.h> 16 17#include <asm/uaccess.h> 18#include <linux/sunrpc/types.h> 19#include <linux/sunrpc/sched.h> 20#include <linux/sunrpc/stats.h> 21 22/* 23 * Declare the debug flags here 24 */ 25unsigned int rpc_debug; 26unsigned int nfs_debug; 27unsigned int nfsd_debug; 28unsigned int nlm_debug; 29 30#ifdef RPC_DEBUG 31 32static struct ctl_table_header *sunrpc_table_header; 33static ctl_table sunrpc_table[]; 34 35void 36rpc_register_sysctl(void) 37{ 38 if (!sunrpc_table_header) 39 sunrpc_table_header = register_sysctl_table(sunrpc_table); 40} 41 42void 43rpc_unregister_sysctl(void) 44{ 45 if (sunrpc_table_header) { 46 unregister_sysctl_table(sunrpc_table_header); 47 sunrpc_table_header = NULL; 48 } 49} 50 51static int 52proc_dodebug(ctl_table *table, int write, struct file *file, 53 void __user *buffer, size_t *lenp, loff_t *ppos) 54{ 55 char tmpbuf[20], c, *s; 56 char __user *p; 57 unsigned int value; 58 size_t left, len; 59 60 if ((*ppos && !write) || !*lenp) { 61 *lenp = 0; 62 return 0; 63 } 64 65 left = *lenp; 66 67 if (write) { 68 if (!access_ok(VERIFY_READ, buffer, left)) 69 return -EFAULT; 70 p = buffer; 71 while (left && __get_user(c, p) >= 0 && isspace(c)) 72 left--, p++; 73 if (!left) 74 goto done; 75 76 if (left > sizeof(tmpbuf) - 1) 77 return -EINVAL; 78 if (copy_from_user(tmpbuf, p, left)) 79 return -EFAULT; 80 tmpbuf[left] = '\0'; 81 82 for (s = tmpbuf, value = 0; '0' <= *s && *s <= '9'; s++, left--) 83 value = 10 * value + (*s - '0'); 84 if (*s && !isspace(*s)) 85 return -EINVAL; 86 while (left && isspace(*s)) 87 left--, s++; 88 *(unsigned int *) table->data = value; 89 /* Display the RPC tasks on writing to rpc_debug */ 90 if (table->ctl_name == CTL_RPCDEBUG) { 91 rpc_show_tasks(); 92 } 93 } else { 94 if (!access_ok(VERIFY_WRITE, buffer, left)) 95 return -EFAULT; 96 len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data); 97 if (len > left) 98 len = left; 99 if (__copy_to_user(buffer, tmpbuf, len)) 100 return -EFAULT; 101 if ((left -= len) > 0) { 102 if (put_user('\n', (char __user *)buffer + len)) 103 return -EFAULT; 104 left--; 105 } 106 } 107 108done: 109 *lenp -= left; 110 *ppos += *lenp; 111 return 0; 112} 113 114 115static ctl_table debug_table[] = { 116 { 117 .procname = "rpc_debug", 118 .data = &rpc_debug, 119 .maxlen = sizeof(int), 120 .mode = 0644, 121 .proc_handler = &proc_dodebug 122 }, 123 { 124 .procname = "nfs_debug", 125 .data = &nfs_debug, 126 .maxlen = sizeof(int), 127 .mode = 0644, 128 .proc_handler = &proc_dodebug 129 }, 130 { 131 .procname = "nfsd_debug", 132 .data = &nfsd_debug, 133 .maxlen = sizeof(int), 134 .mode = 0644, 135 .proc_handler = &proc_dodebug 136 }, 137 { 138 .procname = "nlm_debug", 139 .data = &nlm_debug, 140 .maxlen = sizeof(int), 141 .mode = 0644, 142 .proc_handler = &proc_dodebug 143 }, 144 { .ctl_name = 0 } 145}; 146 147static ctl_table sunrpc_table[] = { 148 { 149 .ctl_name = CTL_SUNRPC, 150 .procname = "sunrpc", 151 .mode = 0555, 152 .child = debug_table 153 }, 154 { .ctl_name = 0 } 155}; 156 157#endif