From owner-freebsd-current@FreeBSD.ORG Sun Nov 23 15:57:09 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C7EE216A4CE for ; Sun, 23 Nov 2003 15:57:09 -0800 (PST) Received: from gw.catspoiler.org (217-ip-163.nccn.net [209.79.217.163]) by mx1.FreeBSD.org (Postfix) with ESMTP id 880C643FAF for ; Sun, 23 Nov 2003 15:57:08 -0800 (PST) (envelope-from truckman@FreeBSD.org) Received: from FreeBSD.org (mousie.catspoiler.org [192.168.101.2]) by gw.catspoiler.org (8.12.9p2/8.12.9) with ESMTP id hANNv1eF006528 for ; Sun, 23 Nov 2003 15:57:05 -0800 (PST) (envelope-from truckman@FreeBSD.org) Message-Id: <200311232357.hANNv1eF006528@gw.catspoiler.org> Date: Sun, 23 Nov 2003 15:57:01 -0800 (PST) From: Don Lewis To: current@FreeBSD.org MIME-Version: 1.0 Content-Type: TEXT/plain; charset=us-ascii Subject: null_lookup() vnode locking wierdness X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Nov 2003 23:57:09 -0000 I was trying to figure out why the VOP_UNLOCK() call in null_lookup() was violating a vnode locking assertion, so I tossed a bunch of ASSERT_VOP_LOCKED() calls into null_lookup(). I found something I don't understand ... ASSERT_VOP_LOCKED(dvp, "null_lookup 1"); if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) return (EROFS); /* * Although it is possible to call null_bypass(), we'll do * a direct call to reduce overhead */ ASSERT_VOP_LOCKED(dvp, "null_lookup 2"); ldvp = NULLVPTOLOWERVP(dvp); ASSERT_VOP_LOCKED(dvp, "null_lookup 3"); vp = lvp = NULL; error = VOP_LOOKUP(ldvp, &lvp, cnp); ASSERT_VOP_LOCKED(dvp, "null_lookup 4"); if (error == EJUSTRETURN && (flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME)) error = EROFS; /* * Rely only on the PDIRUNLOCK flag which should be carefully * tracked by underlying filesystem. */ if (cnp->cn_flags & PDIRUNLOCK) VOP_UNLOCK(dvp, LK_THISLAYER, td); The null_lookup {1,2,3} assertions pass, but null_lookup 4 fails. It appears that the VOP_LOOKUP() call to the underlying file system is unlocking the directory vnode in the nullfs file system. How can that happen?