| From: |
| Juan Gomez <juang@us.ibm.com> |
| To: |
| Alan Cox <alan@lxorguk.ukuu.org.uk>, linux-kernel@vger.kernel.org |
| Subject: |
| NFS lockd patch proposal for user-level control of the grace period |
| Date: |
| Tue, 27 Aug 2002 15:06:33 -0600 |
Following up with Alan request here I am sending a patch for fs/lockd/svc.c
that contains the grace period control feature through the proc filesystem,
feedback & sugestions are very welcome as is the prompt inclusion in the
linux distribution :-)
(See attached file: userl-gracep-control.patch)
Regards, Juan
*** svc.c.old Tue Aug 27 20:54:01 2002
--- svc.c Tue Aug 27 20:51:20 2002
***************
*** 35,40 ****
--- 35,42 ----
#include <linux/lockd/lockd.h>
#include <linux/nfs.h>
+ #include <linux/proc_fs.h>
+
#define NLMDBG_FACILITY NLMDBG_SVC
#define LOCKD_BUFSIZE (1024 + NLMSSVC_XDRSIZE)
#define ALLOWED_SIGS (sigmask(SIGKILL))
***************
*** 77,82 ****
--- 79,241 ----
nlmsvc_grace_period = 0;
}
+
+
+ /*
+ * This code enable user-level control of the grace period state of the lockd
+ * daemon.
+ */
+
+
+ /* 1: nlm_proc_fs not intialized, 0: initialized */
+ static int nlm_proc_fs_init_flag = 1;
+
+ static unsigned long grace_period_expire;
+
+
+
+
+ /* Function used to read grace period status of lockd */
+
+ static ssize_t
+ nlmsvc_grace_period_read(char *page,
+ char **start,
+ off_t off,
+ int count,
+ int *eof,
+ void *data)
+ {
+ char *s = nlmsvc_grace_period ? "1" : "0";
+ int len = strlen(s);
+
+ *eof = 0;
+ *start = page;
+
+ if (off < 0)
+ return -EINVAL;
+
+ if (off >= len){
+ *eof = 1;
+ return 0;
+ }
+
+ if (len < (off + count)) {
+
+ *eof = 1;
+ count = len - off;
+
+ } else {
+
+ count = len;
+
+ }
+
+ memcpy(page, s + off, count);
+
+ return count;
+
+ }/* static ssize_t nlmsvc_grace_period_read() */
+
+
+ /*
+ * Set status of entry/binfmt_misc:
+ * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
+ */
+ static int parse_command(const char *buffer, size_t count)
+ {
+ char s[4];
+
+ if (!count)
+ return 0;
+
+ if (count > 3)
+ return -EINVAL;
+
+ memcpy(s, buffer, count);
+
+ if (s[count-1] == '\n')
+ count--;
+
+ if (count == 1 && s[0] == '0')
+ return 1;
+
+ if (count == 1 && s[0] == '1')
+ return 2;
+
+ return -EINVAL;
+
+ }
+
+ /* Function used to set/reset grace period status of lockd */
+
+ static ssize_t nlmsvc_grace_period_write(struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data)
+ {
+ int res = parse_command(buffer, count);
+ struct dentry *root;
+
+ switch (res) {
+ case 1:
+ clear_grace_period();
+ break;
+ case 2:
+ grace_period_expire = set_grace_period();
+ break;
+ default:
+ return res;
+ }
+ return count;
+
+ }/* static ssize_t nlmsvc_grace_period_write() */
+
+
+
+
+
+ static struct proc_dir_entry *base;
+
+
+ static void nlm_proc_fs_init()
+ {
+ struct proc_dir_entry *p;
+
+ if (nlm_proc_fs_init_flag){
+
+ if (!(base = proc_mkdir("nlm", proc_root_fs)))
+ return;
+
+ nlm_proc_fs_init_flag = 0;
+
+ if ((p = create_proc_entry("nlmsvc_grace_period", 0, base))) {
+
+ p->read_proc = nlmsvc_grace_period_read;
+ p->write_proc = nlmsvc_grace_period_write;
+
+ }
+
+ }
+
+ }/* static int nlm_proc_fs_init() */
+
+
+
+
+ static void nlm_proc_fs_exit()
+ {
+
+ if (!nlm_proc_fs_init_flag && base){
+
+ remove_proc_entry("nlmsvc_grace_period", base);
+ remove_proc_entry("nlm", proc_root_fs);
+
+ }
+
+ }/* static void nlm_proc_fs_exit() */
+
+
+
/*
* This is the lockd kernel thread
*/
***************
*** 85,91 ****
{
struct svc_serv *serv = rqstp->rq_server;
int err = 0;
- unsigned long grace_period_expire;
/* Lock module and set up kernel thread */
MOD_INC_USE_COUNT;
--- 244,249 ----
***************
*** 228,233 ****
--- 386,393 ----
if (nlmsvc_pid)
goto out;
+ nlm_proc_fs_init();
+
/*
* Sanity check: if there's no pid,
* we should be the first user ...
***************
*** 291,296 ****
--- 451,459 ----
goto out;
} else
printk(KERN_WARNING "lockd_down: no users! pid=%d\n", nlmsvc_pid);
+
+ nlm_proc_fs_exit();
+
if (!nlmsvc_pid) {
if (warned++ == 0)