diff options
Diffstat (limited to 'fs/lockd/procfs.c')
-rw-r--r-- | fs/lockd/procfs.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/fs/lockd/procfs.c b/fs/lockd/procfs.c new file mode 100644 index 000000000000..2a0a98480e39 --- /dev/null +++ b/fs/lockd/procfs.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * Procfs support for lockd | ||
3 | * | ||
4 | * Copyright (c) 2014 Jeff Layton <jlayton@primarydata.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/fs.h> | ||
8 | #include <linux/proc_fs.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/nsproxy.h> | ||
11 | #include <net/net_namespace.h> | ||
12 | |||
13 | #include "netns.h" | ||
14 | #include "procfs.h" | ||
15 | |||
16 | /* | ||
17 | * We only allow strings that start with 'Y', 'y', or '1'. | ||
18 | */ | ||
19 | static ssize_t | ||
20 | nlm_end_grace_write(struct file *file, const char __user *buf, size_t size, | ||
21 | loff_t *pos) | ||
22 | { | ||
23 | char *data; | ||
24 | struct lockd_net *ln = net_generic(current->nsproxy->net_ns, | ||
25 | lockd_net_id); | ||
26 | |||
27 | if (size < 1) | ||
28 | return -EINVAL; | ||
29 | |||
30 | data = simple_transaction_get(file, buf, size); | ||
31 | if (IS_ERR(data)) | ||
32 | return PTR_ERR(data); | ||
33 | |||
34 | switch(data[0]) { | ||
35 | case 'Y': | ||
36 | case 'y': | ||
37 | case '1': | ||
38 | locks_end_grace(&ln->lockd_manager); | ||
39 | break; | ||
40 | default: | ||
41 | return -EINVAL; | ||
42 | } | ||
43 | |||
44 | return size; | ||
45 | } | ||
46 | |||
47 | static ssize_t | ||
48 | nlm_end_grace_read(struct file *file, char __user *buf, size_t size, | ||
49 | loff_t *pos) | ||
50 | { | ||
51 | struct lockd_net *ln = net_generic(current->nsproxy->net_ns, | ||
52 | lockd_net_id); | ||
53 | char resp[3]; | ||
54 | |||
55 | resp[0] = list_empty(&ln->lockd_manager.list) ? 'Y' : 'N'; | ||
56 | resp[1] = '\n'; | ||
57 | resp[2] = '\0'; | ||
58 | |||
59 | return simple_read_from_buffer(buf, size, pos, resp, sizeof(resp)); | ||
60 | } | ||
61 | |||
62 | static const struct file_operations lockd_end_grace_operations = { | ||
63 | .write = nlm_end_grace_write, | ||
64 | .read = nlm_end_grace_read, | ||
65 | .llseek = default_llseek, | ||
66 | .release = simple_transaction_release, | ||
67 | .owner = THIS_MODULE, | ||
68 | }; | ||
69 | |||
70 | int __init | ||
71 | lockd_create_procfs(void) | ||
72 | { | ||
73 | struct proc_dir_entry *entry; | ||
74 | |||
75 | entry = proc_mkdir("fs/lockd", NULL); | ||
76 | if (!entry) | ||
77 | return -ENOMEM; | ||
78 | entry = proc_create("nlm_end_grace", S_IRUGO|S_IWUSR, entry, | ||
79 | &lockd_end_grace_operations); | ||
80 | if (!entry) { | ||
81 | remove_proc_entry("fs/lockd", NULL); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | void __exit | ||
88 | lockd_remove_procfs(void) | ||
89 | { | ||
90 | remove_proc_entry("fs/lockd/nlm_end_grace", NULL); | ||
91 | remove_proc_entry("fs/lockd", NULL); | ||
92 | } | ||