GNU Linux-libre 5.19-rc6-gnu
[releases.git] / fs / lockd / procfs.c
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 proc_ops lockd_end_grace_proc_ops = {
64         .proc_write     = nlm_end_grace_write,
65         .proc_read      = nlm_end_grace_read,
66         .proc_lseek     = default_llseek,
67         .proc_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_proc_ops);
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 }