All of lore.kernel.org
 help / color / mirror / Atom feed
* nfs NLM locks greater than 8 bytes
@ 2003-11-04  0:52 Bill Akers
  2003-11-05  4:19 ` Trond Myklebust
  0 siblings, 1 reply; 2+ messages in thread
From: Bill Akers @ 2003-11-04  0:52 UTC (permalink / raw)
  To: linux-kernel

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Has anyone looked at the NFS NLM byte lock size issue between the Linux kernel 
based NFS server and BSD 5 clients?  BSD 5 uses a large cookie for locking 
(16 or even 20 bytes).  Linux automatically rejects any lock attempts with a 
cookie over 8 bytes.  This issue has become important for us because of 
Apple's release of OS X 10.3 (Panther), which is based on BSD 5.

Jonathan Lennox summed it up pretty well on the Freebsd bug list:

> Linux's implementation of NFS NLM locks is buggy: it doesn't support lock
> cookies longer than 8 bytes in size.  See the comment in
> <http://lxr.linux.no/source/include/linux/lockd/xdr.h?v=2.6.0-test2> on the
> definition of 'struct nlm_cookie': "NLM cookies. Technically they can be 1K,
> Nobody uses over 8 bytes however."
>
> Unfortunately, this is actually "nobody" except FreeBSD 5.x, which uses
> 16-byte cookies.  As a result, any attempt by a FreeBSD client to lock an
> NFS-mounted file from a Linux server results in the process on the FreeBSD
> client hanging, unkillably.

His full original post is:
http://lists.freebsd.org/pipermail/freebsd-bugs/2003-September/003069.html

I have checked out every recent version of the kernel on kernel.org (2.4 and 
2.6) and haven't seen any modifications to xdr.h or xdr.c that might address 
this issue.  Nor have I been able to find any posts on Linux lists that 
discuss the issue.  There is a BSD patch to dumb down their client code and 
make the cookie size smaller.  The fear being that it will take a long time 
to get a linux patch into the kernel.  But if no one has even brought up the 
issue here, it will certainly take forever.  :-)

I can probably dust off enough of my old coding skills to up the check from 8 
bytes to some higher number (16, 20, 1024 bytes?).  But I certainly don't 
know enough about the Linux kernel to know what ramifications that will have.

Thanks,

- -- 
Bill Akers
Director of Network Operations
UCLA Graduate School of Education and Information Studies
akers@gseis.ucla.edu
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (GNU/Linux)

iD8DBQE/pvhUHuBhMoY9pyIRAn5iAKCpWedBMVY4c41vz1/dNicIx1WJNACcClN2
jf6yR5yyOxTD0i1kx91Tyiw=
=+5DB
-----END PGP SIGNATURE-----



^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: nfs NLM locks greater than 8 bytes
  2003-11-04  0:52 nfs NLM locks greater than 8 bytes Bill Akers
@ 2003-11-05  4:19 ` Trond Myklebust
  0 siblings, 0 replies; 2+ messages in thread
From: Trond Myklebust @ 2003-11-05  4:19 UTC (permalink / raw)
  To: Bill Akers; +Cc: linux-kernel

>>>>> " " == Bill Akers <akers@gseis.ucla.edu> writes:

    >> Unfortunately, this is actually "nobody" except FreeBSD 5.x,
    >> which uses 16-byte cookies.  As a result, any attempt by a
    >> FreeBSD client to lock an NFS-mounted file from a Linux server
    >> results in the process on the FreeBSD client hanging,
    >> unkillably.

     > His full original post is:
     > http://lists.freebsd.org/pipermail/freebsd-bugs/2003-September/003069.html


     "A proper fix would be either to somehow compress all three
     pieces of information -- pid, pid_start, and msg_seq -- into
     eight bytes (difficult); maintain an in-kernel table mapping an
     eight-byte sequence number to lockd_msg_ident; or find some
     other, smaller way of defending against pid recycling."

That's a laugh... They need 16-20 bytes to defend against pid
recycling??? For exactly how many lifetimes of the universe are they
planning on waiting on a lock?

Anyhow, Greg Banks of SGI sent me this patch in March last year. I
haven't been too crazy about it because the debugging code gets a bit
obscurantist.

It will solve your problem though...

Cheers,
  Trond

-------------------------

This patch makes lockd handle NLM cookies larger than 8 bytes, which
is needed for MacOS X interoperability.


diff -ruN --exclude-from=excludes linux-2.4.19.orig/fs/lockd/svclock.c
linux-2.4.19/fs/lockd/svclock.c
--- linux-2.4.19.orig/fs/lockd/svclock.c	Tue Mar  4 19:26:53 2003
+++ linux-2.4.19/fs/lockd/svclock.c	Tue Mar  4 20:32:10 2003
@@ -106,6 +106,7 @@
 {
 	struct nlm_block	**head, *block;
 	struct file_lock	*fl;
+	NLMDBG_COOKIE_BUF
 
 	dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
 				file, lock->fl.fl_pid,
@@ -113,11 +114,11 @@
 				(long long)lock->fl.fl_end, lock->fl.fl_type);
 	for (head = &nlm_blocked; (block = *head); head = &block->b_next) {
 		fl = &block->b_call.a_args.lock.fl;
-		dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%x\n",
+		dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
 				block->b_file, fl->fl_pid,
 				(long long)fl->fl_start,
 				(long long)fl->fl_end, fl->fl_type,
-				*(unsigned int*)(block->b_call.a_args.cookie.data));
+				nlmdbg_cookie2a(&block->b_call.a_args.cookie));
 		if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
 			if (remove) {
 				*head = block->b_next;
@@ -572,12 +573,13 @@
 	struct nlm_rqst		*call = (struct nlm_rqst *) task->tk_calldata;
 	struct nlm_block	*block;
 	unsigned long		timeout;
+	NLMDBG_COOKIE_BUF
 
 	dprintk("lockd: GRANT_MSG RPC callback\n");
-	dprintk("callback: looking for cookie %x \n", 
-		*(unsigned int *)(call->a_args.cookie.data));
+	dprintk("callback: looking for cookie %s \n", 
+		nlmdbg_cookie2a(&call->a_args.cookie));
 	if (!(block = nlmsvc_find_block(&call->a_args.cookie))) {
-		dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data));
+		dprintk("lockd: no block for cookie %s\n", nlmdbg_cookie2a(&call->a_args.cookie));
 		return;
 	}
 
diff -ruN --exclude-from=excludes linux-2.4.19.orig/fs/lockd/xdr.c
linux-2.4.19/fs/lockd/xdr.c
--- linux-2.4.19.orig/fs/lockd/xdr.c	Tue Mar  4 19:26:53 2003
+++ linux-2.4.19/fs/lockd/xdr.c	Tue Mar  4 21:11:12 2003
@@ -55,7 +55,7 @@
 		c->len=4;
 		memset(c->data, 0, 4);	/* hockeypux brain damage */
 	}
-	else if(len<=8)
+	else if(len<=NLM_MAXCOOKIELEN)
 	{
 		c->len=len;
 		memcpy(c->data, p, len);
@@ -64,7 +64,7 @@
 	else 
 	{
 		printk(KERN_NOTICE
-			"lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len);
+			"lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len,
NLM_MAXCOOKIELEN);
 		return NULL;
 	}
 	return p;
@@ -86,7 +86,7 @@
 
 	if ((len = ntohl(*p++)) != NFS2_FHSIZE) {
 		printk(KERN_NOTICE
-			"lockd: bad fhandle size %x (should be %d)\n",
+			"lockd: bad fhandle size %d (should be %d)\n",
 			len, NFS2_FHSIZE);
 		return NULL;
 	}
@@ -534,7 +534,7 @@
  * Buffer requirements for NLM
  */
 #define NLM_void_sz		0
-#define NLM_cookie_sz		3	/* 1 len , 2 data */
+#define NLM_cookie_sz		1+QUADLEN(NLM_MAXCOOKIELEN)
 #define NLM_caller_sz		1+QUADLEN(sizeof(system_utsname.nodename))
 #define NLM_netobj_sz		1+QUADLEN(XDR_MAX_NETOBJ)
 /* #define NLM_owner_sz		1+QUADLEN(NLM_MAXOWNER) */
@@ -644,3 +644,23 @@
 }
 #endif
 
+#ifdef RPC_DEBUG
+const char *__nlmdbg_cookie2a(const struct nlm_cookie *cookie, char *buf, int len)
+{
+	int i;
+
+	len--;	/* allow for trailing \0 */
+	if (len < 3)
+		return "???";
+	for (i = 0 ; i < cookie->len ; i++) {
+		if (len < 2) {
+			strcpy(buf-3, "...");
+			break;
+		}
+		sprintf(buf, "%02x", cookie->data[i]);
+		buf += 2;
+		len -= 2;
+	}
+	*buf = '\0';
+}
+#endif
diff -ruN --exclude-from=excludes linux-2.4.19.orig/fs/lockd/xdr4.c
linux-2.4.19/fs/lockd/xdr4.c
--- linux-2.4.19.orig/fs/lockd/xdr4.c	Tue Mar  4 19:26:53 2003
+++ linux-2.4.19/fs/lockd/xdr4.c	Tue Mar  4 20:37:59 2003
@@ -56,7 +56,7 @@
 		c->len=4;
 		memset(c->data, 0, 4);	/* hockeypux brain damage */
 	}
-	else if(len<=8)
+	else if(len<=NLM_MAXCOOKIELEN)
 	{
 		c->len=len;
 		memcpy(c->data, p, len);
@@ -65,7 +65,7 @@
 	else 
 	{
 		printk(KERN_NOTICE
-			"lockd: bad cookie size %d (only cookies under 8 bytes are supported.)\n", len);
+			"lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len,
NLM_MAXCOOKIELEN);
 		return NULL;
 	}
 	return p;
@@ -540,7 +540,7 @@
  * Buffer requirements for NLM
  */
 #define NLM4_void_sz		0
-#define NLM4_cookie_sz		3	/* 1 len , 2 data */
+#define NLM4_cookie_sz		1+XDR_QUADLEN(NLM_MAXCOOKIELEN)
 #define NLM4_caller_sz		1+XDR_QUADLEN(NLM_MAXSTRLEN)
 #define NLM4_netobj_sz		1+XDR_QUADLEN(XDR_MAX_NETOBJ)
 /* #define NLM4_owner_sz		1+XDR_QUADLEN(NLM4_MAXOWNER) */
diff -ruN --exclude-from=excludes linux-2.4.19.orig/include/linux/lockd/debug.h
linux-2.4.19/include/linux/lockd/debug.h
--- linux-2.4.19.orig/include/linux/lockd/debug.h	Tue Mar  4 19:26:40 2003
+++ linux-2.4.19/include/linux/lockd/debug.h	Tue Mar  4 20:32:10 2003
@@ -49,4 +49,17 @@
 #define NLMDBG_ALL		0x7fff
 
 
+/*
+ * Support for printing NLM cookies in dprintk()
+ */
+#ifdef RPC_DEBUG
+struct nlm_cookie;
+extern const char *__nlmdbg_cookie2a(const struct nlm_cookie *, char *, int);
+#define NLMDBG_COOKIE_BUF   	char __nlmdbg_cookie_buf[2*NLM_MAXCOOKIELEN+1];
+#define nlmdbg_cookie2a(c) \
+    __nlmdbg_cookie2a(__nlmdbg_cookie_buf, sizeof(__nlmdbg_cookie_buf), (c))
+#else
+#define NLMDBG_COOKIE_BUF
+#endif
+
 #endif /* LINUX_LOCKD_DEBUG_H */
diff -ruN --exclude-from=excludes linux-2.4.19.orig/include/linux/lockd/xdr.h
linux-2.4.19/include/linux/lockd/xdr.h
--- linux-2.4.19.orig/include/linux/lockd/xdr.h	Tue Mar  4 19:26:40 2003
+++ linux-2.4.19/include/linux/lockd/xdr.h	Tue Mar  4 20:32:10 2003
@@ -33,14 +33,15 @@
 };
 
 /*
- *	NLM cookies. Technically they can be 1K, Nobody uses over 8 bytes
- *	however.
+ *	NLM cookies. Technically they can be 1K, Few people use over 8 bytes,
+ *	FreeBSD uses 16, Apple Mac OS-X 10.3 uses 20.
  */
  
 struct nlm_cookie
 {
-	unsigned char data[8];
 	unsigned int len;
+#define NLM_MAXCOOKIELEN    	32
+	unsigned char data[NLM_MAXCOOKIELEN];
 };
 
 /*



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2003-11-05  4:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-04  0:52 nfs NLM locks greater than 8 bytes Bill Akers
2003-11-05  4:19 ` Trond Myklebust

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.