18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Procfs support for lockd 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2014 Jeff Layton <jlayton@primarydata.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/fs.h> 98c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/nsproxy.h> 128c2ecf20Sopenharmony_ci#include <net/net_namespace.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include "netns.h" 158c2ecf20Sopenharmony_ci#include "procfs.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * We only allow strings that start with 'Y', 'y', or '1'. 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_cistatic ssize_t 218c2ecf20Sopenharmony_cinlm_end_grace_write(struct file *file, const char __user *buf, size_t size, 228c2ecf20Sopenharmony_ci loff_t *pos) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci char *data; 258c2ecf20Sopenharmony_ci struct lockd_net *ln = net_generic(current->nsproxy->net_ns, 268c2ecf20Sopenharmony_ci lockd_net_id); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci if (size < 1) 298c2ecf20Sopenharmony_ci return -EINVAL; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci data = simple_transaction_get(file, buf, size); 328c2ecf20Sopenharmony_ci if (IS_ERR(data)) 338c2ecf20Sopenharmony_ci return PTR_ERR(data); 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci switch(data[0]) { 368c2ecf20Sopenharmony_ci case 'Y': 378c2ecf20Sopenharmony_ci case 'y': 388c2ecf20Sopenharmony_ci case '1': 398c2ecf20Sopenharmony_ci locks_end_grace(&ln->lockd_manager); 408c2ecf20Sopenharmony_ci break; 418c2ecf20Sopenharmony_ci default: 428c2ecf20Sopenharmony_ci return -EINVAL; 438c2ecf20Sopenharmony_ci } 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci return size; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic ssize_t 498c2ecf20Sopenharmony_cinlm_end_grace_read(struct file *file, char __user *buf, size_t size, 508c2ecf20Sopenharmony_ci loff_t *pos) 518c2ecf20Sopenharmony_ci{ 528c2ecf20Sopenharmony_ci struct lockd_net *ln = net_generic(current->nsproxy->net_ns, 538c2ecf20Sopenharmony_ci lockd_net_id); 548c2ecf20Sopenharmony_ci char resp[3]; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci resp[0] = list_empty(&ln->lockd_manager.list) ? 'Y' : 'N'; 578c2ecf20Sopenharmony_ci resp[1] = '\n'; 588c2ecf20Sopenharmony_ci resp[2] = '\0'; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci return simple_read_from_buffer(buf, size, pos, resp, sizeof(resp)); 618c2ecf20Sopenharmony_ci} 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic const struct proc_ops lockd_end_grace_proc_ops = { 648c2ecf20Sopenharmony_ci .proc_write = nlm_end_grace_write, 658c2ecf20Sopenharmony_ci .proc_read = nlm_end_grace_read, 668c2ecf20Sopenharmony_ci .proc_lseek = default_llseek, 678c2ecf20Sopenharmony_ci .proc_release = simple_transaction_release, 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ciint __init 718c2ecf20Sopenharmony_cilockd_create_procfs(void) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci struct proc_dir_entry *entry; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci entry = proc_mkdir("fs/lockd", NULL); 768c2ecf20Sopenharmony_ci if (!entry) 778c2ecf20Sopenharmony_ci return -ENOMEM; 788c2ecf20Sopenharmony_ci entry = proc_create("nlm_end_grace", S_IRUGO|S_IWUSR, entry, 798c2ecf20Sopenharmony_ci &lockd_end_grace_proc_ops); 808c2ecf20Sopenharmony_ci if (!entry) { 818c2ecf20Sopenharmony_ci remove_proc_entry("fs/lockd", NULL); 828c2ecf20Sopenharmony_ci return -ENOMEM; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci return 0; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_civoid __exit 888c2ecf20Sopenharmony_cilockd_remove_procfs(void) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci remove_proc_entry("fs/lockd/nlm_end_grace", NULL); 918c2ecf20Sopenharmony_ci remove_proc_entry("fs/lockd", NULL); 928c2ecf20Sopenharmony_ci} 93