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