svn commit: r224860 - stable/8/sys/fs/nfsserver

Rick Macklem rmacklem at FreeBSD.org
Sun Aug 14 00:55:19 UTC 2011


Author: rmacklem
Date: Sun Aug 14 00:55:18 2011
New Revision: 224860
URL: http://svn.freebsd.org/changeset/base/224860

Log:
  MFC: r224554
  Fix rename in the new NFS server so that it does not require a
  recursive vnode lock on the directory for the case where the
  new file name is in the same directory as the old one. The patch
  handles this as a special case, recognized by the new directory
  having the same file handle as the old one and just VREF()s the old
  dir vnode for this case, instead of doing a second VFS_FHTOVP() to get it.
  This is required so that the server will work for file systems like
  msdosfs, that do not support recursive vnode locking.
  This problem was discovered during recent testing by pho@
  when exporting an msdosfs file system via the new NFS server.

Modified:
  stable/8/sys/fs/nfsserver/nfs_nfsdserv.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Aug 14 00:42:09 2011	(r224859)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdserv.c	Sun Aug 14 00:55:18 2011	(r224860)
@@ -1425,6 +1425,7 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 	struct nfsrvfh tfh;
 	char *bufp, *tbufp = NULL;
 	u_long *hashp;
+	fhandle_t fh;
 
 	if (nd->nd_repstat) {
 		nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
@@ -1450,19 +1451,34 @@ nfsrvd_rename(struct nfsrv_descript *nd,
 		tnes = *toexp;
 		tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0);
 	} else {
+		tfh.nfsrvfh_len = 0;
 		error = nfsrv_mtofh(nd, &tfh);
+		if (error == 0)
+			error = nfsvno_getfh(dp, &fh, p);
 		if (error) {
 			vput(dp);
 			/* todp is always NULL except NFSv4 */
 			nfsvno_relpathbuf(&fromnd);
 			goto out;
 		}
-		nd->nd_cred->cr_uid = nd->nd_saveduid;
-		nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, 0, p);
-		if (tdp) {
+
+		/* If this is the same file handle, just VREF() the vnode. */
+		if (tfh.nfsrvfh_len == NFSX_MYFH &&
+		    !NFSBCMP(tfh.nfsrvfh_data, &fh, NFSX_MYFH)) {
+			VREF(dp);
+			tdp = dp;
+			tnes = *exp;
 			tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
 			    p, 1);
-			NFSVOPUNLOCK(tdp, 0);
+		} else {
+			nd->nd_cred->cr_uid = nd->nd_saveduid;
+			nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL,
+			    0, p);
+			if (tdp) {
+				tdirfor_ret = nfsvno_getattr(tdp, &tdirfor,
+				    nd->nd_cred, p, 1);
+				NFSVOPUNLOCK(tdp, 0);
+			}
 		}
 	}
 	NFSNAMEICNDSET(&tond.ni_cnd, nd->nd_cred, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART);


More information about the svn-src-all mailing list