xref: /linux/fs/lockd/procfs.c (revision 7c66e12136c2fa421ae75497e02728f252108a1b)
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 };
68 
69 int __init
70 lockd_create_procfs(void)
71 {
72 	struct proc_dir_entry *entry;
73 
74 	entry = proc_mkdir("fs/lockd", NULL);
75 	if (!entry)
76 		return -ENOMEM;
77 	entry = proc_create("nlm_end_grace", S_IRUGO|S_IWUSR, entry,
78 				 &lockd_end_grace_operations);
79 	if (!entry) {
80 		remove_proc_entry("fs/lockd", NULL);
81 		return -ENOMEM;
82 	}
83 	return 0;
84 }
85 
86 void __exit
87 lockd_remove_procfs(void)
88 {
89 	remove_proc_entry("fs/lockd/nlm_end_grace", NULL);
90 	remove_proc_entry("fs/lockd", NULL);
91 }
92