Blame view

fs/nfsd/fault_inject.c 3.66 KB
65178db42   Bryan Schumaker   NFSD: Added fault...
1
2
3
4
5
6
7
8
9
10
  /*
   * Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
   *
   * Uses debugfs to create fault injection points for client testing
   */
  
  #include <linux/types.h>
  #include <linux/fs.h>
  #include <linux/debugfs.h>
  #include <linux/module.h>
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
11
  #include <linux/nsproxy.h>
5976687a2   Jeff Layton   sunrpc: move addr...
12
  #include <linux/sunrpc/addr.h>
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
13
  #include <asm/uaccess.h>
65178db42   Bryan Schumaker   NFSD: Added fault...
14
15
  
  #include "state.h"
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
16
  #include "netns.h"
65178db42   Bryan Schumaker   NFSD: Added fault...
17
18
19
  
  struct nfsd_fault_inject_op {
  	char *file;
285abdee5   Jeff Layton   nfsd: remove old ...
20
21
22
  	u64 (*get)(void);
  	u64 (*set_val)(u64);
  	u64 (*set_clnt)(struct sockaddr_storage *, size_t);
65178db42   Bryan Schumaker   NFSD: Added fault...
23
  };
65178db42   Bryan Schumaker   NFSD: Added fault...
24
  static struct dentry *debug_dir;
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
25
26
27
28
29
  static ssize_t fault_inject_read(struct file *file, char __user *buf,
  				 size_t len, loff_t *ppos)
  {
  	static u64 val;
  	char read_buf[25];
f3e41ec5e   Kinglong Mee   NFSD: Use simple_...
30
  	size_t size;
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
31
  	loff_t pos = *ppos;
c96223d3b   Jeff Layton   nfsd: abstract ou...
32
  	struct nfsd_fault_inject_op *op = file_inode(file)->i_private;
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
33
34
  
  	if (!pos)
285abdee5   Jeff Layton   nfsd: remove old ...
35
  		val = op->get();
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
36
37
  	size = scnprintf(read_buf, sizeof(read_buf), "%llu
  ", val);
f3e41ec5e   Kinglong Mee   NFSD: Use simple_...
38
  	return simple_read_from_buffer(buf, len, ppos, read_buf, size);
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
39
40
41
42
43
  }
  
  static ssize_t fault_inject_write(struct file *file, const char __user *buf,
  				  size_t len, loff_t *ppos)
  {
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
44
  	char write_buf[INET6_ADDRSTRLEN];
18d9a2ca2   Bryan Schumaker   NFSD: Correct the...
45
  	size_t size = min(sizeof(write_buf) - 1, len);
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
46
47
  	struct net *net = current->nsproxy->net_ns;
  	struct sockaddr_storage sa;
c96223d3b   Jeff Layton   nfsd: abstract ou...
48
  	struct nfsd_fault_inject_op *op = file_inode(file)->i_private;
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
49
  	u64 val;
d4c8e34fe   Jeff Layton   nfsd: properly ha...
50
  	char *nl;
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
51
52
53
  
  	if (copy_from_user(write_buf, buf, size))
  		return -EFAULT;
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
54
  	write_buf[size] = '\0';
d4c8e34fe   Jeff Layton   nfsd: properly ha...
55
56
57
58
59
60
61
  	/* Deal with any embedded newlines in the string */
  	nl = strchr(write_buf, '
  ');
  	if (nl) {
  		size = nl - write_buf;
  		*nl = '\0';
  	}
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
62
  	size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa));
c96223d3b   Jeff Layton   nfsd: abstract ou...
63
  	if (size > 0) {
285abdee5   Jeff Layton   nfsd: remove old ...
64
  		val = op->set_clnt(&sa, size);
c96223d3b   Jeff Layton   nfsd: abstract ou...
65
66
67
68
69
  		if (val)
  			pr_info("NFSD [%s]: Client %s had %llu state object(s)
  ",
  				op->file, write_buf, val);
  	} else {
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
70
  		val = simple_strtoll(write_buf, NULL, 0);
c96223d3b   Jeff Layton   nfsd: abstract ou...
71
72
73
74
75
  		if (val == 0)
  			pr_info("NFSD Fault Injection: %s (all)", op->file);
  		else
  			pr_info("NFSD Fault Injection: %s (n = %llu)",
  				op->file, val);
285abdee5   Jeff Layton   nfsd: remove old ...
76
  		val = op->set_val(val);
c96223d3b   Jeff Layton   nfsd: abstract ou...
77
  		pr_info("NFSD: %s: found %llu", op->file, val);
6c1e82a4b   Bryan Schumaker   NFSD: Forget stat...
78
  	}
d7cc431ed   Bryan Schumaker   NFSD: Add a custo...
79
80
81
82
83
84
85
86
  	return len; /* on success, claim we got the whole input */
  }
  
  static const struct file_operations fops_nfsd = {
  	.owner   = THIS_MODULE,
  	.read    = fault_inject_read,
  	.write   = fault_inject_write,
  };
65178db42   Bryan Schumaker   NFSD: Added fault...
87
88
89
90
91
  
  void nfsd_fault_inject_cleanup(void)
  {
  	debugfs_remove_recursive(debug_dir);
  }
c96223d3b   Jeff Layton   nfsd: abstract ou...
92
93
94
  static struct nfsd_fault_inject_op inject_ops[] = {
  	{
  		.file     = "forget_clients",
7ec0e36f1   Jeff Layton   nfsd: add a forge...
95
  		.get	  = nfsd_inject_print_clients,
69fc9edf9   Jeff Layton   nfsd: add nfsd_in...
96
  		.set_val  = nfsd_inject_forget_clients,
a0926d152   Jeff Layton   nfsd: add a forge...
97
  		.set_clnt = nfsd_inject_forget_client,
c96223d3b   Jeff Layton   nfsd: abstract ou...
98
99
100
  	},
  	{
  		.file     = "forget_locks",
016200c37   Jeff Layton   nfsd: add more gr...
101
102
103
  		.get	  = nfsd_inject_print_locks,
  		.set_val  = nfsd_inject_forget_locks,
  		.set_clnt = nfsd_inject_forget_client_locks,
c96223d3b   Jeff Layton   nfsd: abstract ou...
104
105
106
  	},
  	{
  		.file     = "forget_openowners",
82e05efae   Jeff Layton   nfsd: add more gr...
107
108
109
  		.get	  = nfsd_inject_print_openowners,
  		.set_val  = nfsd_inject_forget_openowners,
  		.set_clnt = nfsd_inject_forget_client_openowners,
c96223d3b   Jeff Layton   nfsd: abstract ou...
110
111
112
  	},
  	{
  		.file     = "forget_delegations",
98d5c7c5b   Jeff Layton   nfsd: add more gr...
113
114
115
  		.get	  = nfsd_inject_print_delegations,
  		.set_val  = nfsd_inject_forget_delegations,
  		.set_clnt = nfsd_inject_forget_client_delegations,
c96223d3b   Jeff Layton   nfsd: abstract ou...
116
117
118
  	},
  	{
  		.file     = "recall_delegations",
98d5c7c5b   Jeff Layton   nfsd: add more gr...
119
120
121
  		.get	  = nfsd_inject_print_delegations,
  		.set_val  = nfsd_inject_recall_delegations,
  		.set_clnt = nfsd_inject_recall_client_delegations,
c96223d3b   Jeff Layton   nfsd: abstract ou...
122
123
124
125
  	},
  };
  
  #define NUM_INJECT_OPS (sizeof(inject_ops)/sizeof(struct nfsd_fault_inject_op))
65178db42   Bryan Schumaker   NFSD: Added fault...
126
127
128
129
  int nfsd_fault_inject_init(void)
  {
  	unsigned int i;
  	struct nfsd_fault_inject_op *op;
88187398c   Al Viro   debugfs-related m...
130
  	umode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
65178db42   Bryan Schumaker   NFSD: Added fault...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  
  	debug_dir = debugfs_create_dir("nfsd", NULL);
  	if (!debug_dir)
  		goto fail;
  
  	for (i = 0; i < NUM_INJECT_OPS; i++) {
  		op = &inject_ops[i];
  		if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd))
  			goto fail;
  	}
  	return 0;
  
  fail:
  	nfsd_fault_inject_cleanup();
  	return -ENOMEM;
  }