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
|
/*
* 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/config.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/ctype.h>
#include <linux/fs.h>
#include <linux/sysctl.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/stats.h>
/*
* Declare the debug flags here
*/
unsigned int rpc_debug;
unsigned int nfs_debug;
unsigned int nfsd_debug;
unsigned int nlm_debug;
#ifdef RPC_DEBUG
static struct ctl_table_header *sunrpc_table_header;
static ctl_table sunrpc_table[];
void
rpc_register_sysctl(void)
{
if (!sunrpc_table_header) {
sunrpc_table_header = register_sysctl_table(sunrpc_table, 1);
#ifdef CONFIG_PROC_FS
if (sunrpc_table[0].de)
sunrpc_table[0].de->owner = THIS_MODULE;
#endif
}
}
void
rpc_unregister_sysctl(void)
{
if (sunrpc_table_header) {
unregister_sysctl_table(sunrpc_table_header);
sunrpc_table_header = NULL;
}
}
static 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;
while (left && __get_user(c, p) >= 0 && isspace(c))
left--, p++;
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;
/* Display the RPC tasks on writing to rpc_debug */
if (table->ctl_name == CTL_RPCDEBUG) {
rpc_show_tasks();
}
} 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
|