aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/fault_inject.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-30 08:27:16 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-08-05 10:55:02 -0400
commitc96223d3b6b2794b6262d1a31d35694760cff5b2 (patch)
tree16f5609916d35c98bc2272f6d8163ce4ba5f4c8e /fs/nfsd/fault_inject.c
parent294ac32e99861f6efee548a6b7afb27c32cd502f (diff)
nfsd: abstract out the get and set routines into the fault injection ops
Now that we've added more granular locking in other places, it's time to address the fault injection code. This code is currently quite reliant on the client_mutex for protection. Start to change this by adding a new set of fault injection op vectors. For now they all use the legacy ones. In later patches we'll add new routines that can deal with more granular locking. Also, move some of the printk routines into the callers to make the results of the operations more uniform. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/fault_inject.c')
-rw-r--r--fs/nfsd/fault_inject.c129
1 files changed, 78 insertions, 51 deletions
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index f1333fc35b33..b1159900d934 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -17,79 +17,50 @@
17 17
18struct nfsd_fault_inject_op { 18struct nfsd_fault_inject_op {
19 char *file; 19 char *file;
20 u64 (*get)(struct nfsd_fault_inject_op *);
21 u64 (*set_val)(struct nfsd_fault_inject_op *, u64);
22 u64 (*set_clnt)(struct nfsd_fault_inject_op *,
23 struct sockaddr_storage *, size_t);
20 u64 (*forget)(struct nfs4_client *, u64); 24 u64 (*forget)(struct nfs4_client *, u64);
21 u64 (*print)(struct nfs4_client *, u64); 25 u64 (*print)(struct nfs4_client *, u64);
22}; 26};
23 27
24static struct nfsd_fault_inject_op inject_ops[] = {
25 {
26 .file = "forget_clients",
27 .forget = nfsd_forget_client,
28 .print = nfsd_print_client,
29 },
30 {
31 .file = "forget_locks",
32 .forget = nfsd_forget_client_locks,
33 .print = nfsd_print_client_locks,
34 },
35 {
36 .file = "forget_openowners",
37 .forget = nfsd_forget_client_openowners,
38 .print = nfsd_print_client_openowners,
39 },
40 {
41 .file = "forget_delegations",
42 .forget = nfsd_forget_client_delegations,
43 .print = nfsd_print_client_delegations,
44 },
45 {
46 .file = "recall_delegations",
47 .forget = nfsd_recall_client_delegations,
48 .print = nfsd_print_client_delegations,
49 },
50};
51
52static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
53static struct dentry *debug_dir; 28static struct dentry *debug_dir;
54 29
55static void nfsd_inject_set(struct nfsd_fault_inject_op *op, u64 val) 30static u64 nfsd_inject_set(struct nfsd_fault_inject_op *op, u64 val)
56{ 31{
57 u64 count = 0; 32 u64 count;
58
59 if (val == 0)
60 printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
61 else
62 printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val);
63 33
64 nfs4_lock_state(); 34 nfs4_lock_state();
65 count = nfsd_for_n_state(val, op->forget); 35 count = nfsd_for_n_state(val, op->forget);
66 nfs4_unlock_state(); 36 nfs4_unlock_state();
67 printk(KERN_INFO "NFSD: %s: found %llu", op->file, count); 37 return count;
68} 38}
69 39
70static void nfsd_inject_set_client(struct nfsd_fault_inject_op *op, 40static u64 nfsd_inject_set_client(struct nfsd_fault_inject_op *op,
71 struct sockaddr_storage *addr, 41 struct sockaddr_storage *addr,
72 size_t addr_size) 42 size_t addr_size)
73{ 43{
74 char buf[INET6_ADDRSTRLEN];
75 struct nfs4_client *clp; 44 struct nfs4_client *clp;
76 u64 count; 45 u64 count = 0;
77 46
78 nfs4_lock_state(); 47 nfs4_lock_state();
79 clp = nfsd_find_client(addr, addr_size); 48 clp = nfsd_find_client(addr, addr_size);
80 if (clp) { 49 if (clp)
81 count = op->forget(clp, 0); 50 count = op->forget(clp, 0);
82 rpc_ntop((struct sockaddr *)&clp->cl_addr, buf, sizeof(buf));
83 printk(KERN_INFO "NFSD [%s]: Client %s had %llu state object(s)\n", op->file, buf, count);
84 }
85 nfs4_unlock_state(); 51 nfs4_unlock_state();
52 return count;
86} 53}
87 54
88static void nfsd_inject_get(struct nfsd_fault_inject_op *op, u64 *val) 55static u64 nfsd_inject_get(struct nfsd_fault_inject_op *op)
89{ 56{
57 u64 count;
58
90 nfs4_lock_state(); 59 nfs4_lock_state();
91 *val = nfsd_for_n_state(0, op->print); 60 count = nfsd_for_n_state(0, op->print);
92 nfs4_unlock_state(); 61 nfs4_unlock_state();
62
63 return count;
93} 64}
94 65
95static ssize_t fault_inject_read(struct file *file, char __user *buf, 66static ssize_t fault_inject_read(struct file *file, char __user *buf,
@@ -99,9 +70,10 @@ static ssize_t fault_inject_read(struct file *file, char __user *buf,
99 char read_buf[25]; 70 char read_buf[25];
100 size_t size; 71 size_t size;
101 loff_t pos = *ppos; 72 loff_t pos = *ppos;
73 struct nfsd_fault_inject_op *op = file_inode(file)->i_private;
102 74
103 if (!pos) 75 if (!pos)
104 nfsd_inject_get(file_inode(file)->i_private, &val); 76 val = op->get(op);
105 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val); 77 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);
106 78
107 return simple_read_from_buffer(buf, len, ppos, read_buf, size); 79 return simple_read_from_buffer(buf, len, ppos, read_buf, size);
@@ -114,6 +86,7 @@ static ssize_t fault_inject_write(struct file *file, const char __user *buf,
114 size_t size = min(sizeof(write_buf) - 1, len); 86 size_t size = min(sizeof(write_buf) - 1, len);
115 struct net *net = current->nsproxy->net_ns; 87 struct net *net = current->nsproxy->net_ns;
116 struct sockaddr_storage sa; 88 struct sockaddr_storage sa;
89 struct nfsd_fault_inject_op *op = file_inode(file)->i_private;
117 u64 val; 90 u64 val;
118 char *nl; 91 char *nl;
119 92
@@ -129,11 +102,20 @@ static ssize_t fault_inject_write(struct file *file, const char __user *buf,
129 } 102 }
130 103
131 size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa)); 104 size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa));
132 if (size > 0) 105 if (size > 0) {
133 nfsd_inject_set_client(file_inode(file)->i_private, &sa, size); 106 val = op->set_clnt(op, &sa, size);
134 else { 107 if (val)
108 pr_info("NFSD [%s]: Client %s had %llu state object(s)\n",
109 op->file, write_buf, val);
110 } else {
135 val = simple_strtoll(write_buf, NULL, 0); 111 val = simple_strtoll(write_buf, NULL, 0);
136 nfsd_inject_set(file_inode(file)->i_private, val); 112 if (val == 0)
113 pr_info("NFSD Fault Injection: %s (all)", op->file);
114 else
115 pr_info("NFSD Fault Injection: %s (n = %llu)",
116 op->file, val);
117 val = op->set_val(op, val);
118 pr_info("NFSD: %s: found %llu", op->file, val);
137 } 119 }
138 return len; /* on success, claim we got the whole input */ 120 return len; /* on success, claim we got the whole input */
139} 121}
@@ -149,6 +131,51 @@ void nfsd_fault_inject_cleanup(void)
149 debugfs_remove_recursive(debug_dir); 131 debugfs_remove_recursive(debug_dir);
150} 132}
151 133
134static struct nfsd_fault_inject_op inject_ops[] = {
135 {
136 .file = "forget_clients",
137 .get = nfsd_inject_get,
138 .set_val = nfsd_inject_set,
139 .set_clnt = nfsd_inject_set_client,
140 .forget = nfsd_forget_client,
141 .print = nfsd_print_client,
142 },
143 {
144 .file = "forget_locks",
145 .get = nfsd_inject_get,
146 .set_val = nfsd_inject_set,
147 .set_clnt = nfsd_inject_set_client,
148 .forget = nfsd_forget_client_locks,
149 .print = nfsd_print_client_locks,
150 },
151 {
152 .file = "forget_openowners",
153 .get = nfsd_inject_get,
154 .set_val = nfsd_inject_set,
155 .set_clnt = nfsd_inject_set_client,
156 .forget = nfsd_forget_client_openowners,
157 .print = nfsd_print_client_openowners,
158 },
159 {
160 .file = "forget_delegations",
161 .get = nfsd_inject_get,
162 .set_val = nfsd_inject_set,
163 .set_clnt = nfsd_inject_set_client,
164 .forget = nfsd_forget_client_delegations,
165 .print = nfsd_print_client_delegations,
166 },
167 {
168 .file = "recall_delegations",
169 .get = nfsd_inject_get,
170 .set_val = nfsd_inject_set,
171 .set_clnt = nfsd_inject_set_client,
172 .forget = nfsd_recall_client_delegations,
173 .print = nfsd_print_client_delegations,
174 },
175};
176
177#define NUM_INJECT_OPS (sizeof(inject_ops)/sizeof(struct nfsd_fault_inject_op))
178
152int nfsd_fault_inject_init(void) 179int nfsd_fault_inject_init(void)
153{ 180{
154 unsigned int i; 181 unsigned int i;