Module Name:    src
Committed By:   dholland
Date:           Mon Jul 18 06:45:47 UTC 2011

Modified Files:
        src/sys/ufs/ufs: ufs_vnops.c

Log Message:
Eliminate the old ufs_rename. The only reason the WAPBL one was
different is that in order to avoid issues with the WAPBL journal lock
the wrong locking had to be changed to different wrong locking. This
is now moot.

I have not hand-validated that the current two copies of rename are
equivalent, or that the locking fixes merged with the old rename
produce code that is textually identical (modulo WAPBL calls that do
nothing when WAPBL is turned off) to the WAPBL rename... but I did
this check when preparing my previous round of rename patches last
year and all updates since have been applied to both.


To generate a diff of this commit:
cvs rdiff -u -r1.199 -r1.200 src/sys/ufs/ufs/ufs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ufs/ufs_vnops.c
diff -u src/sys/ufs/ufs/ufs_vnops.c:1.199 src/sys/ufs/ufs/ufs_vnops.c:1.200
--- src/sys/ufs/ufs/ufs_vnops.c:1.199	Mon Jul 18 06:45:27 2011
+++ src/sys/ufs/ufs/ufs_vnops.c	Mon Jul 18 06:45:47 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_vnops.c,v 1.199 2011/07/18 06:45:27 dholland Exp $	*/
+/*	$NetBSD: ufs_vnops.c,v 1.200 2011/07/18 06:45:47 dholland Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.199 2011/07/18 06:45:27 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.200 2011/07/18 06:45:47 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -1300,15 +1300,9 @@
  *    directory was moved and the parent of the destination
  *    is different from the source, patch the ".." entry in the
  *    directory.
- *
- * WAPBL NOTE: wapbl_ufs_rename derived from ufs_rename in ufs_vnops.c
- * ufs_vnops.c netbsd cvs revision 1.108
- * which has the berkeley copyright above
- * changes introduced to ufs_rename since netbsd cvs revision 1.164
- * will need to be ported into wapbl_ufs_rename
  */
 int
-wapbl_ufs_rename(void *v)
+ufs_rename(void *v)
 {
 	struct vop_rename_args  /* {
 		struct vnode		*a_fdvp;
@@ -1970,406 +1964,6 @@
 }
 
 int
-ufs_rename(void *v)
-{
-	struct vop_rename_args  /* {
-		struct vnode		*a_fdvp;
-		struct vnode		*a_fvp;
-		struct componentname	*a_fcnp;
-		struct vnode		*a_tdvp;
-		struct vnode		*a_tvp;
-		struct componentname	*a_tcnp;
-	} */ *ap = v;
-	struct vnode		*tvp, *tdvp, *fvp, *fdvp;
-	struct componentname	*tcnp, *fcnp;
-	struct inode		*ip, *xp, *dp;
-	struct mount		*mp;
-	struct direct		*newdir;
-	int			doingdirectory, oldparent, newparent, error;
-	struct ufs_lookup_results from_ulr, to_ulr;
-
-#ifdef WAPBL
-	if (ap->a_tdvp->v_mount->mnt_wapbl)
-		return wapbl_ufs_rename(v);
-#endif
-
-	tvp = ap->a_tvp;
-	tdvp = ap->a_tdvp;
-	fvp = ap->a_fvp;
-	fdvp = ap->a_fdvp;
-	tcnp = ap->a_tcnp;
-	fcnp = ap->a_fcnp;
-	doingdirectory = oldparent = newparent = error = 0;
-
-	/* save the supplemental lookup results as they currently exist */
-	from_ulr = VTOI(fdvp)->i_crap;
-	to_ulr = VTOI(tdvp)->i_crap;
-	UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
-	UFS_CHECK_CRAPCOUNTER(VTOI(tdvp));
-
-	/*
-	 * Check for cross-device rename.
-	 */
-	if ((fvp->v_mount != tdvp->v_mount) ||
-	    (tvp && (fvp->v_mount != tvp->v_mount))) {
-		error = EXDEV;
- abortit:
-		VOP_ABORTOP(tdvp, tcnp); /* XXX, why not in NFS? */
-		if (tdvp == tvp)
-			vrele(tdvp);
-		else
-			vput(tdvp);
-		if (tvp)
-			vput(tvp);
-		VOP_ABORTOP(fdvp, fcnp); /* XXX, why not in NFS? */
-		vrele(fdvp);
-		vrele(fvp);
-		return (error);
-	}
-
-	/*
-	 * Check if just deleting a link name.
-	 */
-	if (tvp && ((VTOI(tvp)->i_flags & (IMMUTABLE | APPEND)) ||
-	    (VTOI(tdvp)->i_flags & APPEND))) {
-		error = EPERM;
-		goto abortit;
-	}
-	if (fvp == tvp) {
-		if (fvp->v_type == VDIR) {
-			error = EINVAL;
-			goto abortit;
-		}
-
-		/* Release destination completely. */
-		VOP_ABORTOP(tdvp, tcnp);
-		vput(tdvp);
-		vput(tvp);
-
-		/* Delete source. */
-		vrele(fvp);
-		fcnp->cn_flags &= ~(MODMASK);
-		fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
-		fcnp->cn_nameiop = DELETE;
-		vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
-		if ((error = relookup(fdvp, &fvp, fcnp, 0))) {
-			vput(fdvp);
-			return (error);
-		}
-		return (VOP_REMOVE(fdvp, fvp, fcnp));
-	}
-	if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
-		goto abortit;
-	dp = VTOI(fdvp);
-	ip = VTOI(fvp);
-	if ((nlink_t) ip->i_nlink >= LINK_MAX) {
-		VOP_UNLOCK(fvp);
-		error = EMLINK;
-		goto abortit;
-	}
-	if ((ip->i_flags & (IMMUTABLE | APPEND)) ||
-		(dp->i_flags & APPEND)) {
-		VOP_UNLOCK(fvp);
-		error = EPERM;
-		goto abortit;
-	}
-	if ((ip->i_mode & IFMT) == IFDIR) {
-		/*
-		 * Avoid ".", "..", and aliases of "." for obvious reasons.
-		 */
-		if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') ||
-		    dp == ip ||
-		    (fcnp->cn_flags & ISDOTDOT) ||
-		    (tcnp->cn_flags & ISDOTDOT) ||
-		    (ip->i_flag & IN_RENAME)) {
-			VOP_UNLOCK(fvp);
-			error = EINVAL;
-			goto abortit;
-		}
-		ip->i_flag |= IN_RENAME;
-		oldparent = dp->i_number;
-		doingdirectory = 1;
-	}
-	VN_KNOTE(fdvp, NOTE_WRITE);		/* XXXLUKEM/XXX: right place? */
-
-	/*
-	 * When the target exists, both the directory
-	 * and target vnodes are returned locked.
-	 */
-	dp = VTOI(tdvp);
-	xp = NULL;
-	if (tvp)
-		xp = VTOI(tvp);
-
-	mp = fdvp->v_mount;
-	fstrans_start(mp, FSTRANS_SHARED);
-
-	/*
-	 * 1) Bump link count while we're moving stuff
-	 *    around.  If we crash somewhere before
-	 *    completing our work, the link count
-	 *    may be wrong, but correctable.
-	 */
-	ip->i_nlink++;
-	DIP_ASSIGN(ip, nlink, ip->i_nlink);
-	ip->i_flag |= IN_CHANGE;
-	if ((error = UFS_UPDATE(fvp, NULL, NULL, UPDATE_DIROP)) != 0) {
-		VOP_UNLOCK(fvp);
-		goto bad;
-	}
-
-	/*
-	 * If ".." must be changed (ie the directory gets a new
-	 * parent) then the source directory must not be in the
-	 * directory hierarchy above the target, as this would
-	 * orphan everything below the source directory. Also
-	 * the user must have write permission in the source so
-	 * as to be able to change "..". We must repeat the call
-	 * to namei, as the parent directory is unlocked by the
-	 * call to checkpath().
-	 */
-	error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred);
-	VOP_UNLOCK(fvp);
-	if (oldparent != dp->i_number)
-		newparent = dp->i_number;
-	if (doingdirectory && newparent) {
-		if (error)	/* write access check above */
-			goto bad;
-		if (xp != NULL)
-			vput(tvp);
-		vref(tdvp);	/* compensate for the ref checkpath loses */
-		if ((error = ufs_checkpath(ip, dp, tcnp->cn_cred)) != 0) {
-			vrele(tdvp);
-			goto out;
-		}
-		vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY);
-		error = relookup(tdvp, &tvp, tcnp, 0);
-		if (error != 0) {
-			vput(tdvp);
-			goto out;
-		}
-		dp = VTOI(tdvp);
-
-		/* update the supplemental reasults */
-		to_ulr = dp->i_crap;
-		UFS_CHECK_CRAPCOUNTER(dp);
-
-		xp = NULL;
-		if (tvp)
-			xp = VTOI(tvp);
-	}
-	/*
-	 * 2) If target doesn't exist, link the target
-	 *    to the source and unlink the source.
-	 *    Otherwise, rewrite the target directory
-	 *    entry to reference the source inode and
-	 *    expunge the original entry's existence.
-	 */
-	if (xp == NULL) {
-		if (dp->i_dev != ip->i_dev)
-			panic("rename: EXDEV");
-		/*
-		 * Account for ".." in new directory.
-		 * When source and destination have the same
-		 * parent we don't fool with the link count.
-		 */
-		if (doingdirectory && newparent) {
-			if ((nlink_t)dp->i_nlink >= LINK_MAX) {
-				error = EMLINK;
-				goto bad;
-			}
-			dp->i_nlink++;
-			DIP_ASSIGN(dp, nlink, dp->i_nlink);
-			dp->i_flag |= IN_CHANGE;
-			if ((error = UFS_UPDATE(tdvp, NULL, NULL,
-			    UPDATE_DIROP)) != 0) {
-				dp->i_nlink--;
-				DIP_ASSIGN(dp, nlink, dp->i_nlink);
-				dp->i_flag |= IN_CHANGE;
-				goto bad;
-			}
-		}
-		newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK);
-		ufs_makedirentry(ip, tcnp, newdir);
-		error = ufs_direnter(tdvp, &to_ulr,
-				     NULL, newdir, tcnp, NULL);
-		pool_cache_put(ufs_direct_cache, newdir);
-		if (error != 0) {
-			if (doingdirectory && newparent) {
-				dp->i_nlink--;
-				DIP_ASSIGN(dp, nlink, dp->i_nlink);
-				dp->i_flag |= IN_CHANGE;
-				(void)UFS_UPDATE(tdvp, NULL, NULL,
-						 UPDATE_WAIT|UPDATE_DIROP);
-			}
-			goto bad;
-		}
-		VN_KNOTE(tdvp, NOTE_WRITE);
-		vput(tdvp);
-	} else {
-		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
-			panic("rename: EXDEV");
-		/*
-		 * Short circuit rename(foo, foo).
-		 */
-		if (xp->i_number == ip->i_number)
-			panic("rename: same file");
-		/*
-		 * If the parent directory is "sticky", then the user must
-		 * own the parent directory, or the destination of the rename,
-		 * otherwise the destination may not be changed (except by
-		 * root). This implements append-only directories.
-		 */
-		if ((dp->i_mode & S_ISTXT) &&
-		    kauth_authorize_generic(tcnp->cn_cred,
-		     KAUTH_GENERIC_ISSUSER, NULL) != 0 &&
-		    kauth_cred_geteuid(tcnp->cn_cred) != dp->i_uid &&
-		    xp->i_uid != kauth_cred_geteuid(tcnp->cn_cred)) {
-			error = EPERM;
-			goto bad;
-		}
-		/*
-		 * Target must be empty if a directory and have no links
-		 * to it. Also, ensure source and target are compatible
-		 * (both directories, or both not directories).
-		 */
-		if ((xp->i_mode & IFMT) == IFDIR) {
-			if (xp->i_nlink > 2 ||
-			    !ufs_dirempty(xp, dp->i_number, tcnp->cn_cred)) {
-				error = ENOTEMPTY;
-				goto bad;
-			}
-			if (!doingdirectory) {
-				error = ENOTDIR;
-				goto bad;
-			}
-			cache_purge(tdvp);
-		} else if (doingdirectory) {
-			error = EISDIR;
-			goto bad;
-		}
-		if ((error = ufs_dirrewrite(dp, to_ulr.ulr_offset,
-		    xp, ip->i_number,
-		    IFTODT(ip->i_mode), doingdirectory && newparent ?
-		    newparent : doingdirectory, IN_CHANGE | IN_UPDATE)) != 0)
-			goto bad;
-		if (doingdirectory) {
-			/*
-			 * Truncate inode. The only stuff left in the directory
-			 * is "." and "..". The "." reference is inconsequential
-			 * since we are quashing it. We have removed the "."
-			 * reference and the reference in the parent directory,
-			 * but there may be other hard links.
-			 */
-			if (!newparent) {
-				dp->i_nlink--;
-				DIP_ASSIGN(dp, nlink, dp->i_nlink);
-				dp->i_flag |= IN_CHANGE;
-			}
-			xp->i_nlink--;
-			DIP_ASSIGN(xp, nlink, xp->i_nlink);
-			xp->i_flag |= IN_CHANGE;
-			if ((error = UFS_TRUNCATE(tvp, (off_t)0, IO_SYNC,
-			    tcnp->cn_cred)))
-				goto bad;
-		}
-		VN_KNOTE(tdvp, NOTE_WRITE);
-		vput(tdvp);
-		VN_KNOTE(tvp, NOTE_DELETE);
-		vput(tvp);
-		xp = NULL;
-	}
-
-	/*
-	 * 3) Unlink the source.
-	 */
-	fcnp->cn_flags &= ~(MODMASK);
-	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
-	vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
-	if ((error = relookup(fdvp, &fvp, fcnp, 0))) {
-		vput(fdvp);
-		vrele(ap->a_fvp);
-		goto out2;
-	}
-	/* update supplemental lookup results */
-	from_ulr = VTOI(fdvp)->i_crap;
-	UFS_CHECK_CRAPCOUNTER(VTOI(fdvp));
-
-	if (fvp != NULL) {
-		xp = VTOI(fvp);
-		dp = VTOI(fdvp);
-	} else {
-		/*
-		 * From name has disappeared.
-		 */
-		if (doingdirectory)
-			panic("rename: lost dir entry");
-		vrele(ap->a_fvp);
-		error = 0;
-		goto out2;
-	}
-	/*
-	 * Ensure that the directory entry still exists and has not
-	 * changed while the new name has been entered. If the source is
-	 * a file then the entry may have been unlinked or renamed. In
-	 * either case there is no further work to be done. If the source
-	 * is a directory then it cannot have been rmdir'ed; The IRENAME
-	 * flag ensures that it cannot be moved by another rename or removed
-	 * by a rmdir.
-	 */
-	if (xp != ip) {
-		if (doingdirectory)
-			panic("rename: lost dir entry");
-	} else {
-		/*
-		 * If the source is a directory with a
-		 * new parent, the link count of the old
-		 * parent directory must be decremented
-		 * and ".." set to point to the new parent.
-		 */
-		if (doingdirectory && newparent) {
-			KASSERT(dp != NULL);
-			ufs_dirrewrite(xp, mastertemplate.dot_reclen,
-			    dp, newparent, DT_DIR, 0, IN_CHANGE);
-			cache_purge(fdvp);
-		}
-		error = ufs_dirremove(fdvp, &from_ulr,
-				      xp, fcnp->cn_flags, 0);
-		xp->i_flag &= ~IN_RENAME;
-	}
-	VN_KNOTE(fvp, NOTE_RENAME);
-	if (dp)
-		vput(fdvp);
-	if (xp)
-		vput(fvp);
-	vrele(ap->a_fvp);
-	goto out2;
-
-	/* exit routines from steps 1 & 2 */
- bad:
-	if (xp)
-		vput(ITOV(xp));
-	vput(ITOV(dp));
- out:
-	if (doingdirectory)
-		ip->i_flag &= ~IN_RENAME;
-	if (vn_lock(fvp, LK_EXCLUSIVE) == 0) {
-		ip->i_nlink--;
-		DIP_ASSIGN(ip, nlink, ip->i_nlink);
-		ip->i_flag |= IN_CHANGE;
-		ip->i_flag &= ~IN_RENAME;
-		vput(fvp);
-	} else
-		vrele(fvp);
-	vrele(fdvp);
-
-	/* exit routines from step 3 */
- out2:
-	fstrans_done(mp);
-	return (error);
-}
-
-int
 ufs_mkdir(void *v)
 {
 	struct vop_mkdir_args /* {

Reply via email to