svn commit: r354274 - projects/nfsv42/sys/fs/nfsserver

Rick Macklem rmacklem at FreeBSD.org
Sun Nov 3 03:16:24 UTC 2019


Author: rmacklem
Date: Sun Nov  3 03:16:23 2019
New Revision: 354274
URL: https://svnweb.freebsd.org/changeset/base/354274

Log:
  Fix vnode locking for the case where Seek is proxied to the DS server.
  
  When a Seek is done on a pNFS server, the Seek is proxied to the DS
  server. This requires that the vnode remain locked until after the
  proxied Seek is completed. This patch fixes the vnode locking for Seek
  so that the vnode remains locked until after the proxy call and then
  unlocks it just before the VOP_IOCTL() call.

Modified:
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
  projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Sun Nov  3 02:52:41 2019	(r354273)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdport.c	Sun Nov  3 03:16:23 2019	(r354274)
@@ -5871,6 +5871,8 @@ out:
 
 /*
  * Seek vnode op call (actually it is a VOP_IOCTL()).
+ * This function is called with the vnode locked, but unlocks and vrele()s
+ * the vp before returning.
  */
 int
 nfsvno_seek(struct nfsrv_descript *nd, struct vnode *vp, u_long cmd,
@@ -5879,21 +5881,24 @@ nfsvno_seek(struct nfsrv_descript *nd, struct vnode *v
 	struct nfsvattr at;
 	int error, ret;
 
-	ASSERT_VOP_UNLOCKED(vp, "nfsvno_seek vp");
+	ASSERT_VOP_LOCKED(vp, "nfsvno_seek vp");
 	/*
 	 * Attempt to seek on a DS file. A return of ENOENT implies
 	 * there is no DS file to seek on.
 	 */
 	error = nfsrv_proxyds(vp, 0, 0, cred, p, NFSPROC_SEEKDS, NULL,
 	    NULL, NULL, NULL, NULL, offp, content, eofp);
-	if (error != ENOENT)
+	if (error != ENOENT) {
+		vput(vp);
 		return (error);
+	}
 
 	/*
 	 * Do the VOP_IOCTL() call.  For the case where *offp == file_size,
 	 * VOP_IOCTL() will return ENXIO.  However, the correct reply for
 	 * NFSv4.2 is *eofp == true and error == 0 for this case.
 	 */
+	NFSVOPUNLOCK(vp, 0);
 	error = VOP_IOCTL(vp, cmd, offp, 0, cred, p);
 	*eofp = false;
 	if (error == ENXIO || (error == 0 && cmd == FIOSEEKHOLE)) {
@@ -5906,6 +5911,7 @@ nfsvno_seek(struct nfsrv_descript *nd, struct vnode *v
 		if (ret != 0 && error == 0)
 			error = ret;
 	}
+	vrele(vp);
 	NFSEXITCODE(error);
 	return (error);
 }

Modified: projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Nov  3 02:52:41 2019	(r354273)
+++ projects/nfsv42/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Nov  3 03:16:23 2019	(r354274)
@@ -5472,10 +5472,9 @@ nfsrvd_seek(struct nfsrv_descript *nd, __unused int is
 	if (nd->nd_repstat != 0)
 		goto nfsmout;
 
-	NFSVOPUNLOCK(vp, 0);
+	/* nfsvno_seek() unlocks and vrele()s the vp. */
 	nd->nd_repstat = nfsvno_seek(nd, vp, cmd, &off, content, &eof,
 	    nd->nd_cred, curthread);
-	vrele(vp);
 	if (nd->nd_repstat == 0 && eof && content == NFSV4CONTENT_DATA &&
 	    nfsrv_linux42server != 0)
 		nd->nd_repstat = NFSERR_NXIO;


More information about the svn-src-projects mailing list