Blame view
fs/nfsd/fault_inject.c
3.66 KB
65178db42 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 NFSD: Forget stat... |
11 |
#include <linux/nsproxy.h> |
5976687a2 sunrpc: move addr... |
12 |
#include <linux/sunrpc/addr.h> |
d7cc431ed NFSD: Add a custo... |
13 |
#include <asm/uaccess.h> |
65178db42 NFSD: Added fault... |
14 15 |
#include "state.h" |
6c1e82a4b NFSD: Forget stat... |
16 |
#include "netns.h" |
65178db42 NFSD: Added fault... |
17 18 19 |
struct nfsd_fault_inject_op { char *file; |
285abdee5 nfsd: remove old ... |
20 21 22 |
u64 (*get)(void); u64 (*set_val)(u64); u64 (*set_clnt)(struct sockaddr_storage *, size_t); |
65178db42 NFSD: Added fault... |
23 |
}; |
65178db42 NFSD: Added fault... |
24 |
static struct dentry *debug_dir; |
d7cc431ed 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 NFSD: Use simple_... |
30 |
size_t size; |
d7cc431ed NFSD: Add a custo... |
31 |
loff_t pos = *ppos; |
c96223d3b nfsd: abstract ou... |
32 |
struct nfsd_fault_inject_op *op = file_inode(file)->i_private; |
d7cc431ed NFSD: Add a custo... |
33 34 |
if (!pos) |
285abdee5 nfsd: remove old ... |
35 |
val = op->get(); |
d7cc431ed NFSD: Add a custo... |
36 37 |
size = scnprintf(read_buf, sizeof(read_buf), "%llu ", val); |
f3e41ec5e NFSD: Use simple_... |
38 |
return simple_read_from_buffer(buf, len, ppos, read_buf, size); |
d7cc431ed 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 NFSD: Forget stat... |
44 |
char write_buf[INET6_ADDRSTRLEN]; |
18d9a2ca2 NFSD: Correct the... |
45 |
size_t size = min(sizeof(write_buf) - 1, len); |
6c1e82a4b NFSD: Forget stat... |
46 47 |
struct net *net = current->nsproxy->net_ns; struct sockaddr_storage sa; |
c96223d3b nfsd: abstract ou... |
48 |
struct nfsd_fault_inject_op *op = file_inode(file)->i_private; |
d7cc431ed NFSD: Add a custo... |
49 |
u64 val; |
d4c8e34fe nfsd: properly ha... |
50 |
char *nl; |
d7cc431ed NFSD: Add a custo... |
51 52 53 |
if (copy_from_user(write_buf, buf, size)) return -EFAULT; |
6c1e82a4b NFSD: Forget stat... |
54 |
write_buf[size] = '\0'; |
d4c8e34fe 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 NFSD: Forget stat... |
62 |
size = rpc_pton(net, write_buf, size, (struct sockaddr *)&sa, sizeof(sa)); |
c96223d3b nfsd: abstract ou... |
63 |
if (size > 0) { |
285abdee5 nfsd: remove old ... |
64 |
val = op->set_clnt(&sa, size); |
c96223d3b 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 NFSD: Forget stat... |
70 |
val = simple_strtoll(write_buf, NULL, 0); |
c96223d3b 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 nfsd: remove old ... |
76 |
val = op->set_val(val); |
c96223d3b nfsd: abstract ou... |
77 |
pr_info("NFSD: %s: found %llu", op->file, val); |
6c1e82a4b NFSD: Forget stat... |
78 |
} |
d7cc431ed 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 NFSD: Added fault... |
87 88 89 90 91 |
void nfsd_fault_inject_cleanup(void) { debugfs_remove_recursive(debug_dir); } |
c96223d3b nfsd: abstract ou... |
92 93 94 |
static struct nfsd_fault_inject_op inject_ops[] = { { .file = "forget_clients", |
7ec0e36f1 nfsd: add a forge... |
95 |
.get = nfsd_inject_print_clients, |
69fc9edf9 nfsd: add nfsd_in... |
96 |
.set_val = nfsd_inject_forget_clients, |
a0926d152 nfsd: add a forge... |
97 |
.set_clnt = nfsd_inject_forget_client, |
c96223d3b nfsd: abstract ou... |
98 99 100 |
}, { .file = "forget_locks", |
016200c37 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 nfsd: abstract ou... |
104 105 106 |
}, { .file = "forget_openowners", |
82e05efae 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 nfsd: abstract ou... |
110 111 112 |
}, { .file = "forget_delegations", |
98d5c7c5b 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 nfsd: abstract ou... |
116 117 118 |
}, { .file = "recall_delegations", |
98d5c7c5b 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 nfsd: abstract ou... |
122 123 124 125 |
}, }; #define NUM_INJECT_OPS (sizeof(inject_ops)/sizeof(struct nfsd_fault_inject_op)) |
65178db42 NFSD: Added fault... |
126 127 128 129 |
int nfsd_fault_inject_init(void) { unsigned int i; struct nfsd_fault_inject_op *op; |
88187398c debugfs-related m... |
130 |
umode_t mode = S_IFREG | S_IRUSR | S_IWUSR; |
65178db42 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; } |