From owner-svn-src-head@FreeBSD.ORG Sun May 17 19:33:48 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D4C4E106566C; Sun, 17 May 2009 19:33:48 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B7FF08FC14; Sun, 17 May 2009 19:33:48 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4HJXm3f037588; Sun, 17 May 2009 19:33:48 GMT (envelope-from rmacklem@svn.freebsd.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4HJXmC0037587; Sun, 17 May 2009 19:33:48 GMT (envelope-from rmacklem@svn.freebsd.org) Message-Id: <200905171933.n4HJXmC0037587@svn.freebsd.org> From: Rick Macklem Date: Sun, 17 May 2009 19:33:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192256 - head/sys/fs/nfsserver X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 17 May 2009 19:33:49 -0000 Author: rmacklem Date: Sun May 17 19:33:48 2009 New Revision: 192256 URL: http://svn.freebsd.org/changeset/base/192256 Log: Fix the acquisition of local locks via VOP_ADVLOCK() by the experimental nfsv4 server. It was setting the a_id argument to a fixed value, but that wasn't sufficient for FreeBSD8. Instead, set l_pid and l_sysid to 0 plus set the F_REMOTE flag to indicate that these fields are used to check for same lock owner. Since, for NFSv4, a lockowner is a ClientID plus an up to 1024byte name, it can't be put in l_sysid easily. I also renamed the p variable to td, since it's a thread ptr. Approved by: kib (mentor) Modified: head/sys/fs/nfsserver/nfs_nfsdport.c Modified: head/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdport.c Sun May 17 17:54:01 2009 (r192255) +++ head/sys/fs/nfsserver/nfs_nfsdport.c Sun May 17 19:33:48 2009 (r192256) @@ -2749,14 +2749,13 @@ nfsvno_getvp(fhandle_t *fhp) return (vp); } -static int id_for_advlock; /* * Check to see it a byte range lock held by a process running * locally on the server conflicts with the new lock. */ int nfsvno_localconflict(struct vnode *vp, int ftype, u_int64_t first, - u_int64_t end, struct nfslockconflict *cfp, struct thread *p) + u_int64_t end, struct nfslockconflict *cfp, struct thread *td) { int error; struct flock fl; @@ -2771,11 +2770,20 @@ nfsvno_localconflict(struct vnode *vp, i else fl.l_len = (off_t)(end - first); /* - * FreeBSD8 doesn't like 0, so I'll use the address of id_for_advlock. + * For FreeBSD8, the l_pid and l_sysid must be set to the same + * values for all calls, so that all locks will be held by the + * nfsd server. (The nfsd server handles conflicts between the + * various clients.) + * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 + * bytes, so it can't be put in l_sysid. */ - NFSVOPUNLOCK(vp, 0, p); - error = VOP_ADVLOCK(vp, &id_for_advlock, F_GETLK, &fl, F_POSIX); - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); + fl.l_pid = (pid_t)0; + fl.l_sysid = 0; + + NFSVOPUNLOCK(vp, 0, td); + error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_GETLK, &fl, + (F_POSIX | F_REMOTE)); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); if (error) return (error); if (fl.l_type == F_UNLCK) @@ -2804,7 +2812,7 @@ nfsvno_localconflict(struct vnode *vp, i */ int nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, - u_int64_t end, struct thread *p) + u_int64_t end, struct thread *td) { int error; struct flock fl; @@ -2822,11 +2830,20 @@ nfsvno_advlock(struct vnode *vp, int fty fl.l_len = (off_t)tlen; } /* - * FreeBSD8 doesn't like 0, so I'll use the address of id_for_advlock. + * For FreeBSD8, the l_pid and l_sysid must be set to the same + * values for all calls, so that all locks will be held by the + * nfsd server. (The nfsd server handles conflicts between the + * various clients.) + * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 + * bytes, so it can't be put in l_sysid. */ - NFSVOPUNLOCK(vp, 0, p); - error = VOP_ADVLOCK(vp, &id_for_advlock, F_SETLK, &fl, F_POSIX); - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); + fl.l_pid = (pid_t)0; + fl.l_sysid = 0; + + NFSVOPUNLOCK(vp, 0, td); + error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl, + (F_POSIX | F_REMOTE)); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); return (error); }