From nobody Tue Apr 18 01:35:45 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Q0mhf1Cs4z45VYt; Tue, 18 Apr 2023 01:35:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Q0mhd43sVz3K5D; Tue, 18 Apr 2023 01:35:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1681781745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qZRXxTbX2nu46NRwPSmMSSM7MnxSkRLd8CD+PGDTlEs=; b=xP2nrNXjSee88yI/yiPRlcS5GcqC5nrmUlQBWBR+aPbr5Dbi4YbePRNV1JMAieX3kyfYVm z8Sh9+JN2WMTDjSh2Im0abzPc4PRgcaBCQzZ3iwPbJcgyneWPKfx1kY9P1o3Ocv4YhZrRl Ek6n1dUDDZK58EnbB0zg+gA399GQyzpRZc4qQfNNGXlA6kFac9ix7/QrSrhX6VbHSyr9pe a8OaFkJlt9AUWsUnS6XPlmUs3fJYeT1B8XeN6eeerjFNJhsjCXjq3H6SfvBCGH7Dnk0d6t iPuOkH17gjoFlBpTTysiy4tvS2KdGKuowqJIVpHvB3yKdmR1ZcB1iZxw0vSC2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1681781745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=qZRXxTbX2nu46NRwPSmMSSM7MnxSkRLd8CD+PGDTlEs=; b=oPZAj6rBFf0DtQOyqyvB64dlfBFpGq3ikF3OtMtoN46L5PogV39rFCb0l+GrmgN8zGwbWt EznaRJN7rTgbGPKLGRDqZMBWQiw7GdDut29reQeru6biGBeedgjxox0JZeoX3HPvRNSNHk +SAnXJjIcD2lkR04OW/zC55F/FKWgr7+pZeP3lFp5d6W6KivLlXfX3tIzocUtwYw5T36fo zMey39e3vE15eFTFK1C/iJc4ViOvxjirp9LaKV8/+utW49sv3No/QMKRDnlB75JlOS3Hup FjlH/5Hlpy1vHpqxE6NkcEfrDkyHXLcg6fqxJ3VrEp9/5/cCMh4Mwr6P6c+QPw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1681781745; a=rsa-sha256; cv=none; b=PmYnahAbgpzzMcvqH6Ip0+c9/ubogog/WBq2vOf/9kG7W0WBWNfP7yMW2GuqhCO3dIbK9m LpQNgOOTu9ASAG17nlfx+4vR8YDT+QpUXnXVR7oobahbuwQRNb7wMKOOfgz7rdm1HGYV7d qLc1qcSH3ridz9uaDwYobLMKPIKMr3oA/Fg6M/mUSetQw5eci1PD7e5e5kINWJK6GuE4zE m4O9h/jwjx23fMNmxSWYCdVIGVkgWhh7lNxmiCNLHzeQyv81+GZJKJ7fmFuXYI1VthaYGV 8QMnHL1BcghHigqXVrCIRc8SdU8euR1XrlgQch8fO+dCZl3uDtoJC2d+g/5o5Q== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Q0mhd2vwJzsY6; Tue, 18 Apr 2023 01:35:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33I1ZjMU042464; Tue, 18 Apr 2023 01:35:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33I1Zj6q042463; Tue, 18 Apr 2023 01:35:45 GMT (envelope-from git) Date: Tue, 18 Apr 2023 01:35:45 GMT Message-Id: <202304180135.33I1Zj6q042463@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Jason A. Harmening" Subject: git: 93fe61afde72 - main - unionfs_mkdir(): handle dvp reclamation List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jah X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 93fe61afde72e6841251ea43551631c30556032d Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=93fe61afde72e6841251ea43551631c30556032d commit 93fe61afde72e6841251ea43551631c30556032d Author: Jason A. Harmening AuthorDate: 2023-01-16 21:50:59 +0000 Commit: Jason A. Harmening CommitDate: 2023-04-18 01:31:40 +0000 unionfs_mkdir(): handle dvp reclamation The underlying VOP_MKDIR() implementation may temporarily drop the parent directory vnode's lock. If the vnode is reclaimed during that window, the unionfs vnode will effectively become unlocked because the its v_vnlock field will be reset. To uphold the locking requirements of VOP_MKDIR() and to avoid triggering various VFS assertions, explicitly re-lock the unionfs vnode before returning in this case. Note that there are almost certainly other cases in which we'll similarly need to handle vnode relocking by the underlying FS; this is the only one that's caused problems in stress testing so far. A more general solution, such as that employed for nullfs in null_bypass(), will likely need to be implemented. Tested by: pho Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D39272 --- sys/fs/unionfs/union_vnops.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 0da5ecb61bb2..6c8086a6c7c5 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/union_vnops.c @@ -1389,6 +1389,7 @@ unionfs_mkdir(struct vop_mkdir_args *ap) { struct unionfs_node *dunp; struct componentname *cnp; + struct vnode *dvp; struct vnode *udvp; struct vnode *uvp; struct vattr va; @@ -1400,17 +1401,19 @@ unionfs_mkdir(struct vop_mkdir_args *ap) KASSERT_UNIONFS_VNODE(ap->a_dvp); error = EROFS; - dunp = VTOUNIONFS(ap->a_dvp); + dvp = ap->a_dvp; + dunp = VTOUNIONFS(dvp); cnp = ap->a_cnp; lkflags = cnp->cn_lkflags; udvp = dunp->un_uppervp; if (udvp != NULLVP) { + vref(udvp); /* check opaque */ if (!(cnp->cn_flags & ISWHITEOUT)) { error = VOP_GETATTR(udvp, &va, cnp->cn_cred); if (error != 0) - return (error); + goto unionfs_mkdir_cleanup; if ((va.va_flags & OPAQUE) != 0) cnp->cn_flags |= ISWHITEOUT; } @@ -1418,13 +1421,35 @@ unionfs_mkdir(struct vop_mkdir_args *ap) if ((error = VOP_MKDIR(udvp, &uvp, cnp, ap->a_vap)) == 0) { VOP_UNLOCK(uvp); cnp->cn_lkflags = LK_EXCLUSIVE; - error = unionfs_nodeget(ap->a_dvp->v_mount, uvp, NULLVP, - ap->a_dvp, ap->a_vpp, cnp); + /* + * The underlying VOP_MKDIR() implementation may have + * temporarily dropped the parent directory vnode lock. + * Because the unionfs vnode ordinarily shares that + * lock, this may allow the unionfs vnode to be reclaimed + * and its lock field reset. In that case, the unionfs + * vnode is effectively no longer locked, and we must + * explicitly lock it before returning in order to meet + * the locking requirements of VOP_MKDIR(). + */ + if (__predict_false(VTOUNIONFS(dvp) == NULL)) { + error = ENOENT; + goto unionfs_mkdir_cleanup; + } + error = unionfs_nodeget(dvp->v_mount, uvp, NULLVP, + dvp, ap->a_vpp, cnp); cnp->cn_lkflags = lkflags; vrele(uvp); } } +unionfs_mkdir_cleanup: + + if (__predict_false(VTOUNIONFS(dvp) == NULL)) { + vput(udvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + } else if (udvp != NULLVP) + vrele(udvp); + UNIONFS_INTERNAL_DEBUG("unionfs_mkdir: leave (%d)\n", error); return (error);