Messages in this thread Patch in this message | | | Subject | Re: nfs NLM locks greater than 8 bytes | From | Trond Myklebust <> | Date | 04 Nov 2003 23:19:53 -0500 |
| |
>>>>> " " == 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]; }; /*
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |