Module Name:    src
Committed By:   hannken
Date:           Fri Aug  5 08:17:48 UTC 2011

Modified Files:
        src/sys/fs/union: union_vnops.c
        src/tests/fs/vfs: t_union.c

Log Message:
When union_lookup() creates a shadow directory and nameiop is not LOOKUP
it has to restart the lookup to get the componentname right.

Fixes PR #44383 (an endless stream of whiteout and opaque dir problems ...)


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/fs/union/union_vnops.c
cvs rdiff -u -r1.6 -r1.7 src/tests/fs/vfs/t_union.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/union/union_vnops.c
diff -u src/sys/fs/union/union_vnops.c:1.40 src/sys/fs/union/union_vnops.c:1.41
--- src/sys/fs/union/union_vnops.c:1.40	Sun Jun 12 03:35:55 2011
+++ src/sys/fs/union/union_vnops.c	Fri Aug  5 08:17:47 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: union_vnops.c,v 1.40 2011/06/12 03:35:55 rmind Exp $	*/
+/*	$NetBSD: union_vnops.c,v 1.41 2011/08/05 08:17:47 hannken Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.40 2011/06/12 03:35:55 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.41 2011/08/05 08:17:47 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -304,6 +304,7 @@
 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
 		return (EROFS);
 
+start:
 	upperdvp = dun->un_uppervp;
 	lowerdvp = dun->un_lowervp;
 	uppervp = NULLVP;
@@ -483,6 +484,9 @@
 			 * We may be racing another process to make the
 			 * upper-level shadow directory.  Be careful with
 			 * locks/etc!
+			 * If we have to create a shadow directory and want
+			 * to commit the node we have to restart the lookup
+			 * to get the componentname right.
 			 */
 			if (upperdvp) {
 				dun->un_flags &= ~UN_ULOCK;
@@ -491,6 +495,12 @@
 				    &uppervp);
 				vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY);
 				dun->un_flags |= UN_ULOCK;
+				if (uerror == 0 && cnp->cn_nameiop != LOOKUP) {
+					vput(uppervp);
+					if (lowervp != NULLVP)
+						vput(lowervp);
+					goto start;
+				}
 			}
 			if (uerror) {
 				if (lowervp != NULLVP) {

Index: src/tests/fs/vfs/t_union.c
diff -u src/tests/fs/vfs/t_union.c:1.6 src/tests/fs/vfs/t_union.c:1.7
--- src/tests/fs/vfs/t_union.c:1.6	Wed Aug  3 10:03:51 2011
+++ src/tests/fs/vfs/t_union.c	Fri Aug  5 08:17:47 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_union.c,v 1.6 2011/08/03 10:03:51 hannken Exp $	*/
+/*	$NetBSD: t_union.c,v 1.7 2011/08/05 08:17:47 hannken Exp $	*/
 
 #include <sys/types.h>
 #include <sys/mount.h>
@@ -177,7 +177,6 @@
 	mountunion(mp, lower);
 
 	/* all file systems fail sooner or later */
-	atf_tc_expect_fail("PR kern/44383");
 	FSTEST_ENTER();
 	RL(rump_sys_rmdir(TDIR));
 	ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDFILE, &sb) == -1);

Reply via email to