PERFORCE change 131878 for review

Roman Divacky rdivacky at FreeBSD.org
Fri Dec 28 06:24:23 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=131878

Change 131878 by rdivacky at rdivacky_witten on 2007/12/28 14:24:10

	Implement the fd->vnode translation in the namei routine instead in the consumers.
	This is raceless and prefered method.
	
	Suggested by: jhb, kib

Affected files ...

.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linprocfs/linprocfs.c#5 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/pecoff/imgact_pecoff.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/coda/coda_vfsops.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/msdosfs/msdosfs_vfsops.c#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/nullfs/null_vfsops.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/fs/unionfs/union_vfsops.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_jail.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_acl.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_extattr.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#11 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_mount.c#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#54 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/security/mac/mac_syscalls.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/namei.h#7 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/ufs/ffs/ffs_snapshot.c#4 edit

Differences ...

==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linprocfs/linprocfs.c#5 (text+ko) ====

@@ -47,6 +47,7 @@
 #include <sys/blist.h>
 #include <sys/conf.h>
 #include <sys/exec.h>
+#include <sys/fcntl.h>
 #include <sys/filedesc.h>
 #include <sys/jail.h>
 #include <sys/kernel.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/pecoff/imgact_pecoff.c#4 (text+ko) ====

@@ -45,6 +45,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/fcntl.h>
 #include <sys/imgact.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/coda/coda_vfsops.c#3 (text+ko) ====

@@ -46,6 +46,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/msdosfs/msdosfs_vfsops.c#7 (text+ko) ====

@@ -52,6 +52,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/conf.h>
+#include <sys/fcntl.h>
 #include <sys/iconv.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/nullfs/null_vfsops.c#4 (text+ko) ====

@@ -42,6 +42,7 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/fs/unionfs/union_vfsops.c#3 (text+ko) ====

@@ -39,6 +39,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kdb.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_jail.c#4 (text+ko) ====

@@ -22,6 +22,7 @@
 #include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/taskqueue.h>
+#include <sys/fcntl.h>
 #include <sys/jail.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_acl.c#3 (text+ko) ====

@@ -40,6 +40,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/mount.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_extattr.c#3 (text+ko) ====

@@ -37,6 +37,7 @@
 #include <sys/mount.h>
 #include <sys/mutex.h>
 #include <sys/sysproto.h>
+#include <sys/fcntl.h>
 #include <sys/namei.h>
 #include <sys/filedesc.h>
 #include <sys/limits.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#11 (text+ko) ====

@@ -193,16 +193,43 @@
 	ndp->ni_rootdir = fdp->fd_rdir;
 	ndp->ni_topdir = fdp->fd_jdir;
 
-	if (ndp->ni_startdir)
-		dp = ndp->ni_startdir;
-	else {
+	if (ndp->ni_dirfd != AT_FDCWD) {
+		struct vnode *dvp;
+
+		error = fgetvp(td, ndp->ni_dirfd, &dvp);
+		/* XXX: should we check for relative path too? */
+		if (error) {
+			FILEDESC_SUNLOCK(fdp);
+			uma_zfree(namei_zone, cnp->cn_pnbuf);
+#ifdef DIAGNOSTIC
+			cnp->cn_pnbuf = NULL;
+			cnp->cn_nameptr = NULL;
+#endif
+			return (error);
+		}
+		if (dvp->v_type != VDIR) {
+			vrele(dvp);
+			if (cnp->cn_pnbuf[0] != '/') {
+				FILEDESC_SUNLOCK(fdp);
+				uma_zfree(namei_zone, cnp->cn_pnbuf);
+#ifdef DIAGNOSTIC
+				cnp->cn_pnbuf = NULL;
+				cnp->cn_nameptr = NULL;
+#endif
+				return (ENOTDIR);
+			} else {
+				dvp = fdp->fd_cdir;
+				VREF(dvp);
+			}
+		}
+		dp = dvp;
+	} else {
 		dp = fdp->fd_cdir;
-		/* we might have raced so check it */
-		if ((cnp->cn_flags & ATBADF) && (cnp->cn_pnbuf[0] != '/'))
-			return (EBADF);
 	}
 	vfslocked = VFS_LOCK_GIANT(dp->v_mount);
-	VREF(dp);
+	/* the vnode for the other case was already referenced */
+	if (ndp->ni_dirfd == AT_FDCWD)
+		VREF(dp);
 	FILEDESC_SUNLOCK(fdp);
 	for (;;) {
 		/*
@@ -1023,7 +1050,6 @@
 	char *ptr, *buf, *cp;
 	size_t len, sz;
 	int error;
-	struct vnode *dir_vn;
 
 	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
 	*pathbuf = buf;
@@ -1056,10 +1082,8 @@
 		goto keeporig;
 	}
 
-	if (dirfd == AT_FDCWD)
-		dir_vn = NULL;
-	else {
-	   	/* 
+	if (dirfd != AT_FDCWD) {
+		/*
 		 * we want the original because the "prefix"
 		 * is included in the already opened dirfd
 		 */
@@ -1067,7 +1091,6 @@
 		return (0);
 	}
 
-
 	/*
 	 * We know that there is a / somewhere in this pathname.
 	 * Search backwards for it, to find the file's parent dir
@@ -1080,13 +1103,13 @@
 		for (cp = &ptr[len] - 1; *cp != '/'; cp--);
 		*cp = '\0';
 
-		NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn);
+		NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td);
 		error = namei(&nd);
 		*cp = '/';
 		if (error != 0)
 			goto keeporig;
 	} else {
-		NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn);
+		NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td);
 
 		error = namei(&nd);
 		if (error != 0)

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_mount.c#7 (text+ko) ====

@@ -40,6 +40,7 @@
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/clock.h>
+#include <sys/fcntl.h>
 #include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/libkern.h>

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#54 (text+ko) ====

@@ -85,10 +85,8 @@
 static int setfflags(struct thread *td, struct vnode *, int);
 static int setutimes(struct thread *td, struct vnode *,
     const struct timespec *, int, int);
-static int kern_get_at(struct thread *td, int dirfd, struct vnode **dvpp);
 static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
     struct thread *td);
-static int kern_absolute_path(const char *path, enum uio_seg pathseg);
 
 /*
  * The module initialization routine for POSIX asynchronous I/O will
@@ -1018,53 +1016,11 @@
 	return (kern_openat(td, AT_FDCWD, (const char *)path, pathseg, flags, mode));
 }
 
-static int
-kern_get_at(struct thread *td, int dirfd, struct vnode **dvpp)
-{
-	int error;
-
-	if (dirfd == AT_FDCWD)
-		*dvpp = NULL;
-	else {
-		error = fgetvp(td, dirfd, dvpp);
-		if (error) {
-		   	*dvpp = NULL;
-			return (error);
-		}
-		if ((*dvpp)->v_type != VDIR) {
-			vrele(*dvpp);
-			*dvpp = NULL;
-			return (ENOTDIR);
-		}
-		if (VFS_NEEDSGIANT((*dvpp)->v_mount))
-			mtx_lock(&Giant);
-	}
-
-	return (0);
-}
-
-/* Check whether a path is an absolute path. */
-static int kern_absolute_path(const char *path, enum uio_seg pathseg)
-{
-	int error;
-	char buf[1];
-
-	if (pathseg == UIO_SYSSPACE) {
-		return (path[0] == '/');		
-	} else {
-		error = copyin(path, buf, 1);
-		if (error)
-			return 0;	/* We want to fail. */
-		return (buf[0] == '/');	
-	}
-}
-
 int
 kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
     int flags, int mode)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
 	struct file *fp;
@@ -1081,12 +1037,8 @@
 	AUDIT_ARG(mode, mode);
 	/* XXX: audit dirfd */
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | AUDITVNODE1 |
-	    MPSAFE, pathseg, path, td, dvp);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | AUDITVNODE1 |
+	    MPSAFE, pathseg, path, td, fd);
 
 	if ((flags & O_ACCMODE) == O_ACCMODE) {
 		error = EINVAL;
@@ -1198,21 +1150,11 @@
 	td->td_retval[0] = indx;
 	return (0);
 out:
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 bad:
 	VFS_UNLOCK_GIANT(vfslocked);
 	fdclose(fdp, fp, indx, td);
 	fdrop(fp, td);
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -1288,13 +1230,13 @@
 kern_mknodat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
     int mode, int dev)
 {
-	struct vnode *vp, *dvp = NULL;
+	struct vnode *vp;
 	struct mount *mp;
 	struct vattr vattr;
 	int error;
 	int whiteout = 0;
 	struct nameidata nd;
-	int vfslocked, dvfslocked;
+	int vfslocked;
 
 	AUDIT_ARG(mode, mode);
 	AUDIT_ARG(dev, dev);
@@ -1317,25 +1259,10 @@
 		return (error);
 	bwillwrite();
 restart:
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-		bwillwrite();
-	}
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
+	NDINIT_AT(&nd, CREATE, 0 | LOCKPARENT |
+	    SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
+	if ((error = namei(&nd)) != 0)
 		return (error);
-	NDINIT_AT(&nd, CREATE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
-	if ((error = namei(&nd)) != 0) {
-		if (dvp) {
-			dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-			vrele(dvp);
-			VFS_UNLOCK_GIANT(dvfslocked);
-		}
-		return (error);
-	}
 	vfslocked = NDHASGIANT(&nd);
 	vp = nd.ni_vp;
 	if (vp != NULL) {
@@ -1346,11 +1273,6 @@
 			vput(nd.ni_dvp);
 		vrele(vp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if (dvp) {
-			dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-			vrele(dvp);
-			VFS_UNLOCK_GIANT(dvfslocked);
-		}
 		return (EEXIST);
 	} else {
 		VATTR_NULL(&vattr);
@@ -1382,14 +1304,8 @@
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vput(nd.ni_dvp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) {
-			if (dvp) {
-				dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-				vrele(dvp);
-				VFS_UNLOCK_GIANT(dvfslocked);
-			}
+		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
 			return (error);
-		}
 		goto restart;
 	}
 #ifdef MAC
@@ -1408,11 +1324,6 @@
 				vput(nd.ni_vp);
 		}
 	}
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-	}
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vput(nd.ni_dvp);
 	vn_finished_write(mp);
@@ -1468,31 +1379,15 @@
 	struct vattr vattr;
 	int error;
 	struct nameidata nd;
-	int vfslocked, dvfslocked;
-	struct vnode *dvp = NULL;
+	int vfslocked;
 
 	AUDIT_ARG(mode, mode);
 	bwillwrite();
 restart:
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-		bwillwrite();
-	}
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
+	NDINIT_AT(&nd, CREATE, 0 | LOCKPARENT |
+	    SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
+	if ((error = namei(&nd)) != 0)
 		return (error);
-	NDINIT_AT(&nd, CREATE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    SAVENAME | MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
-	if ((error = namei(&nd)) != 0) {
-		if (dvp) {
-			dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-			vrele(dvp);
-			VFS_UNLOCK_GIANT(dvfslocked);
-		}
-		return (error);
-	}
 	vfslocked = NDHASGIANT(&nd);
 	if (nd.ni_vp != NULL) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -1502,25 +1397,14 @@
 			vput(nd.ni_dvp);
 		vrele(nd.ni_vp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if (dvp) {
-			dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-			vrele(dvp);
-			VFS_UNLOCK_GIANT(dvfslocked);
-		}
 		return (EEXIST);
 	}
 	if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vput(nd.ni_dvp);
 		VFS_UNLOCK_GIANT(vfslocked);
-		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) {
-			if (dvp) {
-				dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-				vrele(dvp);
-				VFS_UNLOCK_GIANT(dvfslocked);
-			}
+		if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
 			return (error);
-	}
 		goto restart;
 	}
 	VATTR_NULL(&vattr);
@@ -1541,11 +1425,6 @@
 #ifdef MAC
 out:
 #endif
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-	}
 	vput(nd.ni_dvp);
 	vn_finished_write(mp);
 	VFS_UNLOCK_GIANT(vfslocked);
@@ -1654,7 +1533,6 @@
     enum uio_seg segflg, int follow)
 {
 	struct nameidata nd;
-	struct vnode *pdvp = NULL, *ldvp = NULL;
 	struct vnode *vp;
 	struct mount *mp;
 	int vfslocked;
@@ -1662,22 +1540,8 @@
 	int error;
 
 	bwillwrite();
-	error = kern_get_at(td, fd1, &pdvp);
-	if (error && !kern_absolute_path(path1, segflg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | follow | MPSAFE |
-	    AUDITVNODE1, segflg, path1, td, pdvp);
-
-	error = kern_get_at(td, fd2, &ldvp);
-	if (error && !kern_absolute_path(path2, segflg)) {
-		if (pdvp) {
-			vfslocked = VFS_NEEDSGIANT(pdvp->v_mount); 
-			vrele(pdvp);
-			VFS_UNLOCK_GIANT(vfslocked);
-		}
-		return (error);
-	}
+	NDINIT_AT(&nd, LOOKUP, 0 | follow | MPSAFE |
+	    AUDITVNODE1, segflg, path1, td, fd1);
 
 	if ((error = namei(&nd)) != 0)
 		goto out;
@@ -1695,8 +1559,8 @@
 		VFS_UNLOCK_GIANT(vfslocked);
 		goto out;
 	}
-	NDINIT_AT(&nd, CREATE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    SAVENAME | MPSAFE | AUDITVNODE1, segflg, path2, td, ldvp);
+	NDINIT_AT(&nd, CREATE, 0 | LOCKPARENT |
+	    SAVENAME | MPSAFE | AUDITVNODE1, segflg, path2, td, fd2);
 	if ((error = namei(&nd)) == 0) {
 		lvfslocked = NDHASGIANT(&nd);
 		if (nd.ni_vp != NULL) {
@@ -1729,16 +1593,6 @@
 	VFS_UNLOCK_GIANT(vfslocked);
 
 out:
-	if (pdvp) {
-		vfslocked = VFS_NEEDSGIANT(pdvp->v_mount); 
-		vrele(pdvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
-	if (ldvp) {
-		vfslocked = VFS_NEEDSGIANT(ldvp->v_mount); 
-		vrele(ldvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -1792,8 +1646,7 @@
 	char *syspath;
 	int error;
 	struct nameidata nd;
-	int vfslocked, dvfslocked;
-	struct vnode *dvp = NULL;
+	int vfslocked;
 
 	if (segflg == UIO_SYSSPACE) {
 		syspath = __DECONST(char *, path1);
@@ -1805,17 +1658,8 @@
 	AUDIT_ARG(text, syspath);
 	bwillwrite();
 restart:
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-		bwillwrite();
-	}
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path2, segflg))
-		return (error);
-	NDINIT_AT(&nd, CREATE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    SAVENAME | MPSAFE | AUDITVNODE1, segflg, path2, td, dvp);
+	NDINIT_AT(&nd, CREATE, 0 | LOCKPARENT |
+	    SAVENAME | MPSAFE | AUDITVNODE1, segflg, path2, td, fd);
 	if ((error = namei(&nd)) != 0)
 		goto out;
 	vfslocked = NDHASGIANT(&nd);
@@ -1861,11 +1705,6 @@
 	vn_finished_write(mp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-	}
 	if (segflg != UIO_SYSSPACE)
 		uma_zfree(namei_zone, syspath);
 	return (error);
@@ -1977,32 +1816,17 @@
 kern_unlinkat(struct thread *td, int fd, const char *path, enum uio_seg pathseg)
 {
 	struct mount *mp;
-	struct vnode *vp, *dvp = NULL;
+	struct vnode *vp;
 	int error;
 	struct nameidata nd;
-	int vfslocked, dvfslocked;
+	int vfslocked;
 
 	bwillwrite();
 restart:
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-		bwillwrite();
-	}
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-	NDINIT_AT(&nd, DELETE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
-	if ((error = namei(&nd)) != 0) {
-		if (dvp) {
-			dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-			vrele(dvp);
-			VFS_UNLOCK_GIANT(dvfslocked);
-		}
+	NDINIT_AT(&nd, DELETE, 0 | LOCKPARENT |
+	    LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
+	if ((error = namei(&nd)) != 0)
 		return (error == EINVAL ? EPERM : error);
-	}
 	vfslocked = NDHASGIANT(&nd);
 	vp = nd.ni_vp;
 	if (vp->v_type == VDIR)
@@ -2026,14 +1850,8 @@
 				vput(vp);
 			VFS_UNLOCK_GIANT(vfslocked);
 			if ((error = vn_start_write(NULL, &mp,
-			    V_XSLEEP | PCATCH)) != 0) {
-				if (dvp) {
-					dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-					vrele(dvp);
-					VFS_UNLOCK_GIANT(dvfslocked);
-				}
+			    V_XSLEEP | PCATCH)) != 0)
 				return (error);
-			}
 			goto restart;
 		}
 #ifdef MAC
@@ -2051,11 +1869,6 @@
 	}
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vput(nd.ni_dvp);
-	if (dvp) {
-		dvfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(dvfslocked);
-	}
 	if (vp == nd.ni_dvp)
 		vrele(vp);
 	else
@@ -2279,19 +2092,14 @@
     int flags)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct ucred *cred, *tmpcred;
 	struct vnode *vp;
 	int vfslocked;
 	int error;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | LOCKLEAF |
+	    MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
 
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | LOCKLEAF |
-	    MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
-
 	/*
 	 * Create and modify a temporary credential instead of one that
 	 * is potentially shared.  This could also mess up socket
@@ -2319,11 +2127,6 @@
 out:
 	td->td_ucred = cred;
 	crfree(tmpcred);
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -2520,16 +2323,11 @@
     struct stat *sbp)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct stat sb;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | LOCKSHARED |
-	    LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, path, td, dvp);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | LOCKSHARED |
+	    LOCKLEAF | AUDITVNODE1 | MPSAFE, pathseg, path, td, fd);
 
 	if ((error = namei(&nd)) != 0)
 		goto out;
@@ -2543,11 +2341,6 @@
 	if (error == 0)
 		*sbp = sb;
 out:	
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -2588,17 +2381,12 @@
     struct stat *sbp)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct vnode *vp;
 	struct stat sb;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | NOFOLLOW | LOCKLEAF |
-	    LOCKSHARED | MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
+	NDINIT_AT(&nd, LOOKUP, 0 | NOFOLLOW | LOCKLEAF |
+	    LOCKSHARED | MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
 	if ((error = namei(&nd)) != 0)
 		goto out;
 	vfslocked = NDHASGIANT(&nd);
@@ -2610,11 +2398,6 @@
 	if (error == 0)
 		*sbp = sb;
 out:	
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -2795,18 +2578,13 @@
     char *buf, enum uio_seg bufseg, int count)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct vnode *vp;
 	struct iovec aiov;
 	struct uio auio;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | NOFOLLOW | LOCKLEAF |
-	    MPSAFE | AUDITVNODE1, pathseg, path, td, dvp);
+	NDINIT_AT(&nd, LOOKUP, 0 | NOFOLLOW | LOCKLEAF |
+	    MPSAFE | AUDITVNODE1, pathseg, path, td, fd);
 
 	if ((error = namei(&nd)) != 0)
 		goto out;
@@ -2839,11 +2617,6 @@
 	VFS_UNLOCK_GIANT(vfslocked);
 	td->td_retval[0] = count - auio.uio_resid;
 out:
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -3074,16 +2847,11 @@
     mode_t mode)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | MPSAFE |
+	    AUDITVNODE1, pathseg, path, td, fd);
 
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | MPSAFE |
-	    AUDITVNODE1, pathseg, path, td, dvp);
-
 	if ((error = namei(&nd)) != 0)
 		goto out;
 	vfslocked = NDHASGIANT(&nd);
@@ -3092,11 +2860,6 @@
 	vrele(nd.ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:	
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -3128,15 +2891,10 @@
 	int error;
 	struct nameidata nd;
 	int vfslocked;
-	struct vnode *dvp;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
 	AUDIT_ARG(mode, mode);
 	NDINIT_AT(&nd, LOOKUP, NOFOLLOW | MPSAFE | AUDITVNODE1, pathseg,
-	    path, td, dvp);
+	    path, td, fd);
 	if ((error = namei(&nd)) != 0)
 		goto out;
 	vfslocked = NDHASGIANT(&nd);
@@ -3145,12 +2903,6 @@
 	vrele(nd.ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
-
 	return (error);
 }
 
@@ -3278,15 +3030,10 @@
     int uid, int gid)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
-
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | MPSAFE |
-	    AUDITVNODE1, pathseg, path, td, dvp);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | MPSAFE |
+	    AUDITVNODE1, pathseg, path, td, fd);
 
 	if ((error = namei(&nd)) != 0)
 		goto out;
@@ -3296,11 +3043,6 @@
 	vrele(nd.ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:	
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -3339,16 +3081,11 @@
     int uid, int gid)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	int error, vfslocked;
 
-	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
+	NDINIT_AT(&nd, LOOKUP, 0 | NOFOLLOW | MPSAFE |
+	    AUDITVNODE1, pathseg, path, td, fd);
 
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | NOFOLLOW | MPSAFE |
-	    AUDITVNODE1, pathseg, path, td, dvp);
-
 	if ((error = namei(&nd)) != 0)
 		goto out;
 	vfslocked = NDHASGIANT(&nd);
@@ -3357,11 +3094,6 @@
 	vrele(nd.ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:	
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -3526,17 +3258,12 @@
     const struct timeval *tptr, enum uio_seg tptrseg)
 {
 	struct nameidata nd;
-	struct vnode *dvp;
 	struct timespec ts[2];
 	int error, vfslocked;
 
-   	error = kern_get_at(td, fd, &dvp);
-	if (error && !kern_absolute_path(path, pathseg))
-		return (error);
+	NDINIT_AT(&nd, LOOKUP, 0 | FOLLOW | MPSAFE |
+	    AUDITVNODE1, pathseg, path, td, fd);
 
-	NDINIT_AT(&nd, LOOKUP, ((error) ? ATBADF : 0) | FOLLOW | MPSAFE |
-	    AUDITVNODE1, pathseg, path, td, dvp);
-
 	if ((error = getutimes(tptr, tptrseg, ts)) != 0)
 		goto out;
 	if ((error = namei(&nd)) != 0)
@@ -3547,11 +3274,6 @@
 	vrele(nd.ni_vp);
 	VFS_UNLOCK_GIANT(vfslocked);
 out:
-	if (dvp) {
-		vfslocked = VFS_NEEDSGIANT(dvp->v_mount); 
-		vrele(dvp);
-		VFS_UNLOCK_GIANT(vfslocked);
-	}
 	return (error);
 }
 
@@ -3947,7 +3669,6 @@
     const char *new, enum uio_seg pathseg)
 {
 	struct nameidata fromnd, tond;
-	struct vnode *frdvp = NULL, *todvp = NULL;
 	struct mount *mp = NULL;
 	struct vnode *tvp, *fvp, *tdvp;
 	int tvfslocked;
@@ -3955,30 +3676,17 @@
 	int error;
 
 	bwillwrite();
-	error = kern_get_at(td, oldfd, &frdvp);
-	if (error && !kern_absolute_path(old, pathseg))
-		return (error);
-
-	error = kern_get_at(td, newfd, &todvp);
-	if (error && !kern_absolute_path(new, pathseg)) {
-		if (frdvp) {
-			fvfslocked = VFS_NEEDSGIANT(frdvp->v_mount); 
-			vrele(frdvp);
-			VFS_UNLOCK_GIANT(fvfslocked);
-		}
-		return (error);
-	}
 
 #ifdef MAC
-	NDINIT_AT(&fromnd, DELETE, ((error) ? ATBADF : 0) | LOCKPARENT |
-	    LOCKLEAF | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, td, frdvp);
+	NDINIT_AT(&fromnd, DELETE, 0 | LOCKPARENT |
+	    LOCKLEAF | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, td, oldfd);
 #else
-	NDINIT_AT(&fromnd, DELETE, ((error) ? ATBADF : 0) | WANTPARENT |
-	    SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, td, frdvp);
+	NDINIT_AT(&fromnd, DELETE, 0 | WANTPARENT |
+	    SAVESTART | MPSAFE | AUDITVNODE1, pathseg, old, td, oldfd);
 #endif
-	NDINIT_AT(&tond, RENAME, ((error) ? ATBADF : 0) | LOCKPARENT |
+	NDINIT_AT(&tond, RENAME, 0 | LOCKPARENT |
 	    LOCKLEAF | NOCACHE | SAVESTART | MPSAFE | AUDITVNODE2,
-	    pathseg, new, td, todvp);
+	    pathseg, new, td, newfd);
 
 	if ((error = namei(&fromnd)) != 0)
 		goto out2;
@@ -4071,16 +3779,6 @@
 	VFS_UNLOCK_GIANT(tvfslocked);

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list