aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/fault_inject.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
index 545f8e4ed101..19f9094bbb07 100644
--- a/fs/nfsd/fault_inject.c
+++ b/fs/nfsd/fault_inject.c
@@ -8,6 +8,7 @@
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/debugfs.h> 9#include <linux/debugfs.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <asm/uaccess.h>
11 12
12#include "state.h" 13#include "state.h"
13 14
@@ -48,10 +49,9 @@ static struct nfsd_fault_inject_op inject_ops[] = {
48static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op); 49static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
49static struct dentry *debug_dir; 50static struct dentry *debug_dir;
50 51
51static int nfsd_inject_set(void *op_ptr, u64 val) 52static void nfsd_inject_set(struct nfsd_fault_inject_op *op, u64 val)
52{ 53{
53 u64 count = 0; 54 u64 count = 0;
54 struct nfsd_fault_inject_op *op = op_ptr;
55 55
56 if (val == 0) 56 if (val == 0)
57 printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file); 57 printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
@@ -62,19 +62,61 @@ static int nfsd_inject_set(void *op_ptr, u64 val)
62 count = nfsd_for_n_state(val, op->forget); 62 count = nfsd_for_n_state(val, op->forget);
63 nfs4_unlock_state(); 63 nfs4_unlock_state();
64 printk(KERN_INFO "NFSD: %s: found %llu", op->file, count); 64 printk(KERN_INFO "NFSD: %s: found %llu", op->file, count);
65 return 0;
66} 65}
67 66
68static int nfsd_inject_get(void *op_ptr, u64 *val) 67static void nfsd_inject_get(struct nfsd_fault_inject_op *op, u64 *val)
69{ 68{
70 struct nfsd_fault_inject_op *op = op_ptr;
71 nfs4_lock_state(); 69 nfs4_lock_state();
72 *val = nfsd_for_n_state(0, op->print); 70 *val = nfsd_for_n_state(0, op->print);
73 nfs4_unlock_state(); 71 nfs4_unlock_state();
74 return 0;
75} 72}
76 73
77DEFINE_SIMPLE_ATTRIBUTE(fops_nfsd, nfsd_inject_get, nfsd_inject_set, "%llu\n"); 74static ssize_t fault_inject_read(struct file *file, char __user *buf,
75 size_t len, loff_t *ppos)
76{
77 static u64 val;
78 char read_buf[25];
79 size_t size, ret;
80 loff_t pos = *ppos;
81
82 if (!pos)
83 nfsd_inject_get(file->f_dentry->d_inode->i_private, &val);
84 size = scnprintf(read_buf, sizeof(read_buf), "%llu\n", val);
85
86 if (pos < 0)
87 return -EINVAL;
88 if (pos >= size || !len)
89 return 0;
90 if (len > size - pos)
91 len = size - pos;
92 ret = copy_to_user(buf, read_buf + pos, len);
93 if (ret == len)
94 return -EFAULT;
95 len -= ret;
96 *ppos = pos + len;
97 return len;
98}
99
100static ssize_t fault_inject_write(struct file *file, const char __user *buf,
101 size_t len, loff_t *ppos)
102{
103 char write_buf[24];
104 size_t size = min(sizeof(write_buf), len) - 1;
105 u64 val;
106
107 if (copy_from_user(write_buf, buf, size))
108 return -EFAULT;
109
110 val = simple_strtoll(write_buf, NULL, 0);
111 nfsd_inject_set(file->f_dentry->d_inode->i_private, val);
112 return len; /* on success, claim we got the whole input */
113}
114
115static const struct file_operations fops_nfsd = {
116 .owner = THIS_MODULE,
117 .read = fault_inject_read,
118 .write = fault_inject_write,
119};
78 120
79void nfsd_fault_inject_cleanup(void) 121void nfsd_fault_inject_cleanup(void)
80{ 122{