Module Name:    src
Committed By:   reinoud
Date:           Tue Jul 16 10:49:36 UTC 2013

Modified Files:
        src/sys/fs/udf: udf_rename.c

Log Message:
Remove udf_node * as state variables and add the loop invariants UFS and tmpfs
carry to make it easier to debug.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/fs/udf/udf_rename.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/fs/udf/udf_rename.c
diff -u src/sys/fs/udf/udf_rename.c:1.9 src/sys/fs/udf/udf_rename.c:1.10
--- src/sys/fs/udf/udf_rename.c:1.9	Mon Jul 15 14:40:21 2013
+++ src/sys/fs/udf/udf_rename.c	Tue Jul 16 10:49:36 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_rename.c,v 1.9 2013/07/15 14:40:21 reinoud Exp $ */
+/* $NetBSD: udf_rename.c,v 1.10 2013/07/16 10:49:36 reinoud Exp $ */
 
 /*
  * Copyright (c) 2013 Reinoud Zandijk
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.9 2013/07/15 14:40:21 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_rename.c,v 1.10 2013/07/16 10:49:36 reinoud Exp $");
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -503,7 +503,8 @@ udf_gro_genealogy(struct mount *mp, kaut
     struct vnode **intermediate_node_ret)
 {
 	struct udf_mount *ump;
-	struct udf_node *source, *target, *parent_node, *child_node;
+	struct udf_node *parent_node;
+	struct vnode *vp, *dvp;
 	struct long_ad parent_loc;
 	const char *name;
 	int namelen;
@@ -532,91 +533,97 @@ udf_gro_genealogy(struct mount *mp, kaut
 	if (error)
 		return error;
 
-	source = VTOI(fdvp);
-	target = VTOI(tdvp);
-
 	name     = "..";
 	namelen  = 2;
 	error    = 0;
 
-	ump = target->ump;
+	ump = VTOI(tdvp)->ump;
 
 	/* if nodes are equal, it is no use looking */
-	KASSERT(udf_compare_icb(&source->loc, &target->loc) != 0);
+	KASSERT(udf_compare_icb(&VTOI(fdvp)->loc, &VTOI(tdvp)->loc) != 0);
 
-	child_node = target;
-	vref(child_node->vnode);
+	/* start at destination vnode and walk up the tree */
+	vp = tdvp;
+	vref(vp);
 
 	for (;;) {
+		KASSERT(vp != NULL);
+		KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
+		KASSERT(vp->v_mount == mp);
+		KASSERT(vp->v_type == VDIR);
+		KASSERT(!udf_rmdired_p(vp));
+
 		DPRINTF(NODE, ("udf_gro_genealogy : "
-			"source vp %p, looking at vp %p\n",
-			source->vnode, child_node->vnode));
+			"fdvp %p, looking at vp %p\n",
+			fdvp, vp));
 
 		/* sanity check */
-		if (child_node->vnode->v_type != VDIR) {
-			vput(child_node->vnode);
+		if (vp->v_type != VDIR) {
+			vput(vp);
 			return ENOTDIR;
 		}
 
 		/* go down one level */
-		error = udf_lookup_name_in_dir(child_node->vnode, name, namelen,
+		error = udf_lookup_name_in_dir(vp, name, namelen,
 			&parent_loc, &found);
 		DPRINTF(NODE, ("\tlookup of parent '..' resulted in error %d, "
 			"found %d\n", error, found));
 		if (!found)
 			error = ENOENT;
 		if (error) {
-			vput(child_node->vnode);
+			vput(vp);
 			return error;
 		}
 
 		/* did we encounter the root node? i.e. loop back */
-		if (udf_compare_icb(&parent_loc, &child_node->loc) == 0) {
+		if (udf_compare_icb(&parent_loc, &VTOI(vp)->loc) == 0) {
 			DPRINTF(NODE, ("ROOT found!\n"));
-			vput(child_node->vnode);
+			vput(vp);
 			*intermediate_node_ret = NULL;
 			return 0;
 		}
 
-		/* did we encounter source node? */
-		if (udf_compare_icb(&parent_loc, &source->loc) == 0) {
-			DPRINTF(NODE, ("SOURCE NODE FOUND\n"));
-			*intermediate_node_ret = child_node->vnode;
-			VOP_UNLOCK(child_node->vnode);
+		/* Did we find that fdvp is an ancestor of tdvp? */
+		if (udf_compare_icb(&parent_loc, &VTOI(fdvp)->loc) == 0) {
+			DPRINTF(NODE, ("fdvp is ancestor of tdvp\n"));
+			*intermediate_node_ret = vp;
+			VOP_UNLOCK(vp);
 			return 0;
 		}
 
 		/*
 		 * Unlock vp so that we can lock the parent, but keep child vp
 		 * referenced until after we have found the parent, so that
-		 * dotdot_ino will not be recycled.
-		 *
-		 * XXX This guarantees that vp's inode number will not be
-		 * recycled, but why can't dotdot_ino be recycled?
+		 * parent_node will not be recycled.
 		 */
 		DPRINTF(NODE, ("\tgetting the parent node\n"));
-		VOP_UNLOCK(child_node->vnode);
+		VOP_UNLOCK(vp);
 		error = udf_get_node(ump, &parent_loc, &parent_node);
-		vrele(child_node->vnode);
+		vrele(vp);
 		if (error) 
 			return error;
 
+		dvp = parent_node->vnode;
+
+		/* switch */
+		KASSERT(dvp != NULL);
+		KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE);
+		vp  = dvp;
+
 		/* sanity check */
-		if (parent_node->vnode->v_type != VDIR) {
+		if (vp->v_type != VDIR) {
 			/* 
 			 * Odd, but can happen if we loose the race and the
 			 * '..' node has been recycled.
 			 */
-			vput(child_node->vnode);
+			vput(vp);
 			return ENOTDIR;
 		}
 
-		if (udf_rmdired_p(parent_node->vnode)) {
-			vput(parent_node->vnode);
+		if (udf_rmdired_p(vp)) {
+			vput(vp);
 			return ENOENT;
 		}
-
-		child_node = parent_node;
 	}
 }
 

Reply via email to