Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lockd: add a /proc/fs/lockd/nlm_end_grace file

Add a new procfile that will allow a (privileged) userland process to
end the NLM grace period early. The basic idea here will be to have
sm-notify write to this file, if it sent out no NOTIFY requests when
it runs. In that situation, we can generally expect that there will be
no reclaim requests so the grace period can be lifted early.

Signed-off-by: Jeff Layton <jlayton@primarydata.com>

authored by

Jeff Layton and committed by
J. Bruce Fields
d68e3c4a 3b3e7b72

+130
+1
fs/lockd/Makefile
··· 7 7 lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \ 8 8 svcshare.o svcproc.o svcsubs.o mon.o xdr.o 9 9 lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o 10 + lockd-objs-$(CONFIG_PROC_FS) += procfs.o 10 11 lockd-objs := $(lockd-objs-y)
+92
fs/lockd/procfs.c
··· 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 + }
+28
fs/lockd/procfs.h
··· 1 + /* 2 + * Procfs support for lockd 3 + * 4 + * Copyright (c) 2014 Jeff Layton <jlayton@primarydata.com> 5 + */ 6 + #ifndef _LOCKD_PROCFS_H 7 + #define _LOCKD_PROCFS_H 8 + 9 + #include <linux/kconfig.h> 10 + 11 + #if IS_ENABLED(CONFIG_PROC_FS) 12 + int lockd_create_procfs(void); 13 + void lockd_remove_procfs(void); 14 + #else 15 + static inline int 16 + lockd_create_procfs(void) 17 + { 18 + return 0; 19 + } 20 + 21 + static inline void 22 + lockd_remove_procfs(void) 23 + { 24 + return; 25 + } 26 + #endif /* IS_ENABLED(CONFIG_PROC_FS) */ 27 + 28 + #endif /* _LOCKD_PROCFS_H */
+9
fs/lockd/svc.c
··· 36 36 #include <linux/nfs.h> 37 37 38 38 #include "netns.h" 39 + #include "procfs.h" 39 40 40 41 #define NLMDBG_FACILITY NLMDBG_SVC 41 42 #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) ··· 621 620 err = register_pernet_subsys(&lockd_net_ops); 622 621 if (err) 623 622 goto err_pernet; 623 + 624 + err = lockd_create_procfs(); 625 + if (err) 626 + goto err_procfs; 627 + 624 628 return 0; 625 629 630 + err_procfs: 631 + unregister_pernet_subsys(&lockd_net_ops); 626 632 err_pernet: 627 633 #ifdef CONFIG_SYSCTL 628 634 unregister_sysctl_table(nlm_sysctl_table); ··· 642 634 { 643 635 /* FIXME: delete all NLM clients */ 644 636 nlm_shutdown_hosts(); 637 + lockd_remove_procfs(); 645 638 unregister_pernet_subsys(&lockd_net_ops); 646 639 #ifdef CONFIG_SYSCTL 647 640 unregister_sysctl_table(nlm_sysctl_table);