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
|
/*
* linux/net/sunrpc/sysctl.c
*
* Sysctl interface to sunrpc module. This is for debugging only now.
*
* I would prefer to register the sunrpc table below sys/net, but that's
* impossible at the moment.
*/
#include <linux/version.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
#if LINUX_VERSION_CODE >= 0x020100
#include <asm/uaccess.h>
#else
# include <linux/mm.h>
# define copy_from_user memcpy_fromfs
# define copy_to_user memcpy_tofs
# define access_ok !verify_area
#endif
#include <linux/sunrpc/types.h>
/*
* Declare the debug flags here
*/
unsigned int rpc_debug = 0;
unsigned int nfs_debug = 0;
unsigned int nfsd_debug = 0;
unsigned int nlm_debug = 0;
#ifdef RPC_DEBUG
static struct ctl_table_header *sunrpc_table_header = NULL;
static ctl_table sunrpc_table[];
void
rpc_register_sysctl(void)
{
if (sunrpc_table_header)
return;
sunrpc_table_header = register_sysctl_table(sunrpc_table, 1);
}
void
rpc_unregister_sysctl(void)
{
if (!sunrpc_table_header)
return;
unregister_sysctl_table(sunrpc_table_header);
}
int
proc_dodebug(ctl_table *table, int write, struct file *file,
void *buffer, size_t *lenp)
{
char tmpbuf[20], *p, c;
unsigned int value;
int left, len;
if ((file->f_pos && !write) || !*lenp) {
*lenp = 0;
return 0;
}
left = *lenp;
if (write) {
if (!access_ok(VERIFY_READ, buffer, left))
return -EFAULT;
p = (char *) buffer;
#if LINUX_VERSION_CODE >= 0x020100
while (left && __get_user(c, p) >= 0 && isspace(c))
left--, p++;
#else
while (left && (c = get_fs_byte(p)) >= 0 && isspace(c))
left--, p++;
#endif
if (!left)
goto done;
if (left > sizeof(tmpbuf) - 1)
return -EINVAL;
copy_from_user(tmpbuf, p, left);
tmpbuf[left] = '\0';
for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
value = 10 * value + (*p - '0');
if (*p && !isspace(*p))
return -EINVAL;
while (left && isspace(*p))
left--, p++;
*(unsigned int *) table->data = value;
} else {
if (!access_ok(VERIFY_WRITE, buffer, left))
return -EFAULT;
len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
if (len > left)
len = left;
copy_to_user(buffer, tmpbuf, len);
if ((left -= len) > 0) {
put_user('\n', (char *)buffer + len);
left--;
}
}
done:
*lenp -= left;
file->f_pos += *lenp;
return 0;
}
#define DIRENTRY(nam1, nam2, child) \
{CTL_##nam1, #nam2, NULL, 0, 0555, child }
#define DBGENTRY(nam1, nam2) \
{CTL_##nam1##DEBUG, #nam2 "_debug", &nam2##_debug, sizeof(int),\
0644, NULL, &proc_dodebug}
static ctl_table debug_table[] = {
DBGENTRY(RPC, rpc),
DBGENTRY(NFS, nfs),
DBGENTRY(NFSD, nfsd),
DBGENTRY(NLM, nlm),
{0}
};
static ctl_table sunrpc_table[] = {
DIRENTRY(SUNRPC, sunrpc, debug_table),
{0}
};
#endif
|