Index: usr.sbin/rpc.lockd/Makefile =================================================================== RCS file: /mnt2/ncvs/src/usr.sbin/rpc.lockd/Makefile,v retrieving revision 1.19 diff -u -u -r1.19 Makefile --- usr.sbin/rpc.lockd/Makefile 26 Oct 2003 06:10:44 -0000 1.19 +++ usr.sbin/rpc.lockd/Makefile 7 Nov 2003 07:24:11 -0000 @@ -9,6 +9,15 @@ CFLAGS+= -I. -I${DESTDIR}/usr/include/rpcsvc #WARNS?= 2 +# At least as of 2.4.23 and 2.6.0pre2, the Linux kernel violates the NFS locking +# protocol by only accepting cookies of size 8 bytes (the spec allows for up to +# 1k in size). By default FreeBSD uses 16 byte cookies; to interoperate with +# broken Linux NFS lockd implementations, uncomment the line below, add +# 'options LINUX_BROKEN_NFS_LOCKING' to your kernel and rebuild the kernel and +# world. +# +#CFLAGS+= -DLINUX_BROKEN_NFS_LOCKING + DPADD= ${LIBRPCSVC} ${LIBUTIL} LDADD= -lrpcsvc -lutil Index: sys/conf/NOTES =================================================================== RCS file: /mnt2/ncvs/src/sys/conf/NOTES,v retrieving revision 1.1186 diff -u -u -r1.1186 NOTES --- sys/conf/NOTES 5 Nov 2003 14:32:27 -0000 1.1186 +++ sys/conf/NOTES 7 Nov 2003 07:22:08 -0000 @@ -767,6 +767,18 @@ options NFS_WDELAYHASHSIZ=16 # and with this options NFS_DEBUG # Enable NFS Debugging +# Linux kernels (as of at least 2.4.23 and 2.6.0pre2) do not conform to +# the NFS locking protocol, and only accept cookies of size 8 bytes. +# By default FreeBSD uses 16-byte cookies; the following enables +# compatibility with the Linux rpc.lockd implementation at the cost of +# removing protection against PID recycling. +# +# If you enable this option in your kernel then you must also edit +# usr.sbin/rpc.lockd/Makefile and uncomment the corresponding line, +# and rebuild the world. +# +options LINUX_BROKEN_NFS_LOCKING + # Coda stuff: options CODA #CODA filesystem. device vcoda 4 #coda minicache <-> venus comm. Index: sys/conf/options =================================================================== RCS file: /mnt2/ncvs/src/sys/conf/options,v retrieving revision 1.424 diff -u -u -r1.424 options --- sys/conf/options 5 Nov 2003 14:37:48 -0000 1.424 +++ sys/conf/options 7 Nov 2003 04:01:40 -0000 @@ -196,6 +196,7 @@ # filesystems will be enabled - but look below. NFSCLIENT opt_nfs.h NFSSERVER opt_nfs.h +LINUX_BROKEN_NFS_LOCKING opt_nfs.h # filesystems and libiconv bridge CD9660_ICONV opt_dontuse.h Index: sys/nfsclient/nfs_lock.c =================================================================== RCS file: /mnt2/ncvs/src/sys/nfsclient/nfs_lock.c,v retrieving revision 1.38 diff -u -u -r1.38 nfs_lock.c --- sys/nfsclient/nfs_lock.c 27 Jul 2003 17:04:56 -0000 1.38 +++ sys/nfsclient/nfs_lock.c 7 Nov 2003 07:12:23 -0000 @@ -117,7 +117,9 @@ p->p_nlminfo->pid_start = p->p_stats->p_start; timevaladd(&p->p_nlminfo->pid_start, &boottime); } +#ifndef LINUX_BROKEN_NFS_LOCKING msg.lm_msg_ident.pid_start = p->p_nlminfo->pid_start; +#endif msg.lm_msg_ident.msg_seq = ++(p->p_nlminfo->msg_seq); msg.lm_fl = *fl; @@ -264,9 +266,11 @@ * is sort of like writing on a pipe after the reader has closed it. */ if (targetp->p_nlminfo == NULL || - ((ansp->la_msg_ident.msg_seq != -1) && - (timevalcmp(&targetp->p_nlminfo->pid_start, + ((ansp->la_msg_ident.msg_seq != -1) && ( +#ifndef LINUX_BROKEN_NFS_LOCKING + timevalcmp(&targetp->p_nlminfo->pid_start, &ansp->la_msg_ident.pid_start, !=) || +#endif targetp->p_nlminfo->msg_seq != ansp->la_msg_ident.msg_seq))) { PROC_UNLOCK(targetp); return (EPIPE); Index: sys/nfsclient/nfs_lock.h =================================================================== RCS file: /mnt2/ncvs/src/sys/nfsclient/nfs_lock.h,v retrieving revision 1.5 diff -u -u -r1.5 nfs_lock.h --- sys/nfsclient/nfs_lock.h 15 Aug 2002 21:52:22 -0000 1.5 +++ sys/nfsclient/nfs_lock.h 7 Nov 2003 07:23:29 -0000 @@ -51,10 +51,19 @@ * a particular message to lockd. A sequence number is used to differentiate * multiple messages from the same process. A process start time is used to * detect the unlikely, but possible, event of the recycling of a pid. + * + * 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 + * before the + * definition of 'struct nlm_cookie': "NLM cookies. Technically they can be 1K, + * Nobody uses over 8 bytes however." (except FreeBSD, MacOS X and possibly + * others). */ struct lockd_msg_ident { pid_t pid; /* The process ID. */ +#ifndef LINUX_BROKEN_NFS_LOCKING struct timeval pid_start; /* Start time of process id */ +#endif int msg_seq; /* Sequence number of message */ };