From nobody Wed Feb 16 00:25:16 2022 X-Original-To: dev-commits-src-branches@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 60B5719CE60A; Wed, 16 Feb 2022 00:25:16 +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 4JyzHw29Khz4SgX; Wed, 16 Feb 2022 00:25:16 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644971116; 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=LTwjpicB6U6OllrqcPHmiTkih9hEYYAaMpZtMszQrTg=; b=QX17xZ654KRkAo2BpWo8G4sDdbqmk1KjGKkXi5ODH/TJ/pfFyaXkvaxo4wjeDVoU2s3wWN VELZvC5PHNjJrvf770+UrvGZ4F59o+cXn8DjeBAvKzMovhKJxLuZorJXc57fUUpJUQP1du fUwbLG1fZJNuy/YtGZCoXyDHqRNCBEglYbIj8JfuAXSTLLiyfOrlI9gH4dT8UGjc2BCk1n YJ5vFbFC2a3flyzJ0nTYoTpjo7RphnmzQyHc/vZr0QuqutILivqOwTUAFH0nPQ+dHuKGWL /mVCwmqpMApw/jrFdLQqYpbaJkZKnuI0bIZhTZipRFCrD+JjsJ0dV8hRD0V0Zg== 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 2609D4603; Wed, 16 Feb 2022 00:25:16 +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 21G0PG8j043743; Wed, 16 Feb 2022 00:25:16 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 21G0PG1G043742; Wed, 16 Feb 2022 00:25:16 GMT (envelope-from git) Date: Wed, 16 Feb 2022 00:25:16 GMT Message-Id: <202202160025.21G0PG1G043742@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kirk McKusick Subject: git: 3364fdf16a00 - stable/13 - ufs: handle LoR between snap lock and vnode lock List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 3364fdf16a006eb3546e3192f0d4803f88fc4e9a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644971116; 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=LTwjpicB6U6OllrqcPHmiTkih9hEYYAaMpZtMszQrTg=; b=Czy3kAy0XAuobUaVBbJythQrADOtetnlR4GiN0vP642aYW+pZwMGDyTuwb2/YMSko2vr6I +qHVd2TF/uV4PrG8DA8PGekUIvven1M4BCt0UanFddiR0CX6qYtpo1PIvPSVlNksJSjRfb 0Fd56qRqrT5xk05ePbmjmku/uja3KXoCXZjxBiMXE3BAaRA9fCrVh4/wTO/Rw1RhX526HI fJ4vBmV7VlIG7IXPz+RnK/mqp9WVAGdFTbpPTPgMRikYRlpC9LmBVWhQFyqxdUjIe4KCzh czWhaY3ehN0YLdo7dEzTuxm0gz3zb1PRkb522ViACbDtBYXyWCslZt30I3L6YA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1644971116; a=rsa-sha256; cv=none; b=SesIas4LcF8geCxHSzousgkm9gDCnWDkhby7vIzdsNRDLdwU2p/S0rSiYG7xvwm08lWAbI PVgubu/lCiJB3AxJ3Pvm0kvMIxX2I3oAutiUQHArqyrT8ylRh+8Mb4VWbqQbp/4d2izWwj xjmvllyys73FuDqkY0qrYLkMEqIbG0NwgRO0OWjCrHhjaHGVqEa4GuocDih+X3Zfq1BOs6 bsgfZnbnVA6ZYkaUdJNchCI4VvPoCz17VYyZ42KmDoqsquESm6kA10bXTeNv04AQ5KZy8G 9guUcpRcrjF/bK0tgp6lwsO2XhH9wkoj9NPKdti7Wu5CWxGLb6O7RXbGSkb/6g== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=3364fdf16a006eb3546e3192f0d4803f88fc4e9a commit 3364fdf16a006eb3546e3192f0d4803f88fc4e9a Author: Kirk McKusick AuthorDate: 2022-01-28 07:00:51 +0000 Commit: Kirk McKusick CommitDate: 2022-02-16 00:01:23 +0000 ufs: handle LoR between snap lock and vnode lock (cherry picked from commit ddf162d1d15f63e871fa1e44334c9461772b7f7a) Differential Revision: https://reviews.freebsd.org/D33946 --- sys/ufs/ffs/ffs_snapshot.c | 86 ++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index cb5c4f5e2481..486288c7e659 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -175,6 +175,7 @@ static int mapacct_ufs2(struct vnode *, ufs2_daddr_t *, ufs2_daddr_t *, struct fs *, ufs_lbn_t, int); static int readblock(struct vnode *vp, struct buf *, ufs2_daddr_t); static void try_free_snapdata(struct vnode *devvp); +static void revert_snaplock(struct vnode *, struct vnode *, struct snapdata *); static struct snapdata *ffs_snapdata_acquire(struct vnode *devvp); static int ffs_bp_snapblk(struct vnode *, struct buf *); @@ -1649,7 +1650,7 @@ ffs_snapremove(vp) struct buf *ibp; struct fs *fs; ufs2_daddr_t numblks, blkno, dblk; - int error, i, last, loc; + int error, last, loc; struct snapdata *sn; ip = VTOI(vp); @@ -1667,20 +1668,10 @@ ffs_snapremove(vp) sn = devvp->v_rdev->si_snapdata; TAILQ_REMOVE(&sn->sn_head, ip, i_nextsnap); ip->i_nextsnap.tqe_prev = 0; - VI_UNLOCK(devvp); - lockmgr(&vp->v_lock, LK_EXCLUSIVE, NULL); - for (i = 0; i < sn->sn_lock.lk_recurse; i++) - lockmgr(&vp->v_lock, LK_EXCLUSIVE, NULL); - KASSERT(vp->v_vnlock == &sn->sn_lock, - ("ffs_snapremove: lost lock mutation")); - vp->v_vnlock = &vp->v_lock; - VI_LOCK(devvp); - while (sn->sn_lock.lk_recurse > 0) - lockmgr(&sn->sn_lock, LK_RELEASE, NULL); - lockmgr(&sn->sn_lock, LK_RELEASE, NULL); + revert_snaplock(vp, devvp, sn); try_free_snapdata(devvp); - } else - VI_UNLOCK(devvp); + } + VI_UNLOCK(devvp); /* * Clear all BLK_NOCOPY fields. Pass any block claims to other * snapshots that want them (see ffs_snapblkfree below). @@ -2156,27 +2147,18 @@ ffs_snapshot_unmount(mp) xp->i_nextsnap.tqe_prev = 0; lockmgr(&sn->sn_lock, LK_INTERLOCK | LK_EXCLUSIVE, VI_MTX(devvp)); - /* - * Avoid LOR with above snapshot lock. The LK_NOWAIT should - * never fail as the lock is currently unused. Rather than - * panic, we recover by doing the blocking lock. - */ - if (lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_NOWAIT, NULL) != 0) { - printf("ffs_snapshot_unmount: Unexpected LK_NOWAIT " - "failure\n"); - lockmgr(&vp->v_lock, LK_EXCLUSIVE, NULL); - } - KASSERT(vp->v_vnlock == &sn->sn_lock, - ("ffs_snapshot_unmount: lost lock mutation")); - vp->v_vnlock = &vp->v_lock; + VI_LOCK(devvp); + revert_snaplock(vp, devvp, sn); lockmgr(&vp->v_lock, LK_RELEASE, NULL); - lockmgr(&sn->sn_lock, LK_RELEASE, NULL); - if (xp->i_effnlink > 0) + if (xp->i_effnlink > 0) { + VI_UNLOCK(devvp); vrele(vp); - VI_LOCK(devvp); + VI_LOCK(devvp); + } sn = devvp->v_rdev->si_snapdata; } try_free_snapdata(devvp); + VI_UNLOCK(devvp); } /* @@ -2680,10 +2662,8 @@ try_free_snapdata(struct vnode *devvp) sn = devvp->v_rdev->si_snapdata; if (sn == NULL || TAILQ_FIRST(&sn->sn_head) != NULL || - (devvp->v_vflag & VV_COPYONWRITE) == 0) { - VI_UNLOCK(devvp); + (devvp->v_vflag & VV_COPYONWRITE) == 0) return; - } devvp->v_rdev->si_snapdata = NULL; devvp->v_vflag &= ~VV_COPYONWRITE; @@ -2695,6 +2675,46 @@ try_free_snapdata(struct vnode *devvp) if (snapblklist != NULL) free(snapblklist, M_UFSMNT); ffs_snapdata_free(sn); + VI_LOCK(devvp); +} + +/* + * Revert a vnode lock from using the snapshot lock back to its own lock. + * + * Aquire a lock on the vnode's own lock and release the lock on the + * snapshot lock. If there are any recursions on the snapshot lock + * get the same number of recursions on the vnode's own lock. + */ +static void +revert_snaplock(vp, devvp, sn) + struct vnode *vp; + struct vnode *devvp; + struct snapdata *sn; +{ + int i; + + ASSERT_VI_LOCKED(devvp, "revert_snaplock"); + /* + * Avoid LOR with snapshot lock. The LK_NOWAIT should + * never fail as the lock is currently unused. Rather than + * panic, we recover by doing the blocking lock. + */ + for (i = 0; i <= sn->sn_lock.lk_recurse; i++) { + if (lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_NOWAIT | + LK_INTERLOCK, VI_MTX(devvp)) != 0) { + printf("revert_snaplock: Unexpected LK_NOWAIT " + "failure\n"); + lockmgr(&vp->v_lock, LK_EXCLUSIVE | LK_INTERLOCK, + VI_MTX(devvp)); + } + VI_LOCK(devvp); + } + KASSERT(vp->v_vnlock == &sn->sn_lock, + ("revert_snaplock: lost lock mutation")); + vp->v_vnlock = &vp->v_lock; + while (sn->sn_lock.lk_recurse > 0) + lockmgr(&sn->sn_lock, LK_RELEASE, NULL); + lockmgr(&sn->sn_lock, LK_RELEASE, NULL); } static struct snapdata *