git: 34116aa48131 - stable/13 - ffs_mount(): fix snapshotting

From: Robert Wing <rew_at_FreeBSD.org>
Date: Wed, 13 Apr 2022 21:04:01 UTC
The branch stable/13 has been updated by rew:

URL: https://cgit.FreeBSD.org/src/commit/?id=34116aa48131d44ddeaa14f7769d013981c0d01b

commit 34116aa48131d44ddeaa14f7769d013981c0d01b
Author:     Robert Wing <rew@FreeBSD.org>
AuthorDate: 2022-03-17 01:27:34 +0000
Commit:     Robert Wing <rew@FreeBSD.org>
CommitDate: 2022-04-13 20:59:12 +0000

    ffs_mount(): fix snapshotting
    
    Commit 0455cc7104ec broke snapshotting for ffs. In that commit,
    ffs_mount() was changed so the namei() lookup for a disk device happens
    before ffs_snapshot(). This caused the issue where namei() would lookup
    the snapshot file and fail because the file doesn't exist. Even if it did
    exist, taking a snapshot would still fail since it's not a disk device.
    
    Fix this by taking a snapshot of the filesystem as-is and return without
    altering ro/rw or any other attributes that are passed in.
    
    Reported by:    pho
    Reviewed by:    mckusick
    Fixes: 0455cc7104ec ("ffs_mount(): return early if namei() fails to lookup disk device")
    Differential Revision:  https://reviews.freebsd.org/D34562
    
    (cherry picked from commit ab2dbd9b871dd00afc6ad78acb386ffa48b6b053)
---
 sys/ufs/ffs/ffs_vfsops.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 2eae7c5fa630..3997c026859c 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -437,6 +437,12 @@ ffs_mount(struct mount *mp)
 	mp->mnt_flag |= mntorflags;
 	MNT_IUNLOCK(mp);
 
+	/*
+	 * If this is a snapshot request, take the snapshot.
+	 */
+	if (mp->mnt_flag & MNT_SNAPSHOT)
+		return (ffs_snapshot(mp, fspec));
+
 	/*
 	 * Must not call namei() while owning busy ref.
 	 */
@@ -711,11 +717,6 @@ ffs_mount(struct mount *mp)
 			MNT_IUNLOCK(mp);
 		}
 
-		/*
-		 * If this is a snapshot request, take the snapshot.
-		 */
-		if (mp->mnt_flag & MNT_SNAPSHOT)
-			return (ffs_snapshot(mp, fspec));
 	}
 
 	MNT_ILOCK(mp);