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 ...)
This commit is contained in:
parent
40cf7e4cfa
commit
efc3d2ec25
@ -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
|
* Copyright (c) 1992, 1993, 1994, 1995
|
||||||
@ -72,7 +72,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -304,6 +304,7 @@ union_lookup(void *v)
|
|||||||
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
|
||||||
return (EROFS);
|
return (EROFS);
|
||||||
|
|
||||||
|
start:
|
||||||
upperdvp = dun->un_uppervp;
|
upperdvp = dun->un_uppervp;
|
||||||
lowerdvp = dun->un_lowervp;
|
lowerdvp = dun->un_lowervp;
|
||||||
uppervp = NULLVP;
|
uppervp = NULLVP;
|
||||||
@ -483,6 +484,9 @@ union_lookup(void *v)
|
|||||||
* We may be racing another process to make the
|
* We may be racing another process to make the
|
||||||
* upper-level shadow directory. Be careful with
|
* upper-level shadow directory. Be careful with
|
||||||
* locks/etc!
|
* 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) {
|
if (upperdvp) {
|
||||||
dun->un_flags &= ~UN_ULOCK;
|
dun->un_flags &= ~UN_ULOCK;
|
||||||
@ -491,6 +495,12 @@ union_lookup(void *v)
|
|||||||
&uppervp);
|
&uppervp);
|
||||||
vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY);
|
vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY);
|
||||||
dun->un_flags |= UN_ULOCK;
|
dun->un_flags |= UN_ULOCK;
|
||||||
|
if (uerror == 0 && cnp->cn_nameiop != LOOKUP) {
|
||||||
|
vput(uppervp);
|
||||||
|
if (lowervp != NULLVP)
|
||||||
|
vput(lowervp);
|
||||||
|
goto start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (uerror) {
|
if (uerror) {
|
||||||
if (lowervp != NULLVP) {
|
if (lowervp != NULLVP) {
|
||||||
|
@ -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/types.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
@ -177,7 +177,6 @@ whiteout(const atf_tc_t *tc, const char *mp)
|
|||||||
mountunion(mp, lower);
|
mountunion(mp, lower);
|
||||||
|
|
||||||
/* all file systems fail sooner or later */
|
/* all file systems fail sooner or later */
|
||||||
atf_tc_expect_fail("PR kern/44383");
|
|
||||||
FSTEST_ENTER();
|
FSTEST_ENTER();
|
||||||
RL(rump_sys_rmdir(TDIR));
|
RL(rump_sys_rmdir(TDIR));
|
||||||
ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDFILE, &sb) == -1);
|
ATF_REQUIRE_ERRNO(ENOENT, rump_sys_stat(TDFILE, &sb) == -1);
|
||||||
|
Loading…
Reference in New Issue
Block a user