xref: /linux/fs/lockd/procfs.c (revision 44f57d78)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Procfs support for lockd
4  *
5  * Copyright (c) 2014 Jeff Layton <jlayton@primarydata.com>
6  */
7 
8 #include <linux/fs.h>
9 #include <linux/proc_fs.h>
10 #include <linux/module.h>
11 #include <linux/nsproxy.h>
12 #include <net/net_namespace.h>
13 
14 #include "netns.h"
15 #include "procfs.h"
16 
17 /*
18  * We only allow strings that start with 'Y', 'y', or '1'.
19  */
20 static ssize_t
21 nlm_end_grace_write(struct file *file, const char __user *buf, size_t size,
22 		    loff_t *pos)
23 {
24 	char *data;
25 	struct lockd_net *ln = net_generic(current->nsproxy->net_ns,
26 					   lockd_net_id);
27 
28 	if (size < 1)
29 		return -EINVAL;
30 
31 	data = simple_transaction_get(file, buf, size);
32 	if (IS_ERR(data))
33 		return PTR_ERR(data);
34 
35 	switch(data[0]) {
36 	case 'Y':
37 	case 'y':
38 	case '1':
39 		locks_end_grace(&ln->lockd_manager);
40 		break;
41 	default:
42 		return -EINVAL;
43 	}
44 
45 	return size;
46 }
47 
48 static ssize_t
49 nlm_end_grace_read(struct file *file, char __user *buf, size_t size,
50 		   loff_t *pos)
51 {
52 	struct lockd_net *ln = net_generic(current->nsproxy->net_ns,
53 					   lockd_net_id);
54 	char resp[3];
55 
56 	resp[0] = list_empty(&ln->lockd_manager.list) ? 'Y' : 'N';
57 	resp[1] = '\n';
58 	resp[2] = '\0';
59 
60 	return simple_read_from_buffer(buf, size, pos, resp, sizeof(resp));
61 }
62 
63 static const struct file_operations lockd_end_grace_operations = {
64 	.write		= nlm_end_grace_write,
65 	.read		= nlm_end_grace_read,
66 	.llseek		= default_llseek,
67 	.release	= simple_transaction_release,
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 }
93