LWN.net Logo

NFS lockd patch proposal for user-level control of the grace period

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)

Copyright © 2002, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds