From 43d09adfe0f532636e6aad7fa6bfed09e4b6adb0 Mon Sep 17 00:00:00 2001 From: Rob Wing Date: Thu, 16 Feb 2023 15:09:13 +0000 Subject: [PATCH] FreeBSD: don't verify recycled vnode for zfs control directory Under certain loads, the following panic is hit: panic: VERIFY3(vrecycle(vp) == 1) failed (0 == 1) cpuid = 17 KDB: stack backtrace: #0 0xffffffff805e29c5 at kdb_backtrace+0x65 #1 0xffffffff8059620f at vpanic+0x17f #2 0xffffffff81a27f4a at spl_panic+0x3a #3 0xffffffff81a3a4d0 at zfsctl_snapshot_inactive+0x40 #4 0xffffffff8066fdee at vinactivef+0xde #5 0xffffffff80670b8a at vgonel+0x1ea #6 0xffffffff806711e1 at vgone+0x31 #7 0xffffffff8065fa0d at vfs_hash_insert+0x26d #8 0xffffffff81a39069 at sfs_vgetx+0x149 #9 0xffffffff81a39c54 at zfsctl_snapdir_lookup+0x1e4 #10 0xffffffff80661c2c at lookup+0x45c #11 0xffffffff80660e59 at namei+0x259 #12 0xffffffff8067e3d3 at kern_statat+0xf3 #13 0xffffffff8067eacf at sys_fstatat+0x2f #14 0xffffffff808b5ecc at amd64_syscall+0x10c #15 0xffffffff8088f07b at fast_syscall_common+0xf8 A race condition can occur when allocating a new vnode and adding that vnode to the vfs hash. If the newly created vnode loses the race when being inserted into the vfs hash, it will not be recycled as its usecount is greater than zero, hitting the above assertion. Fix this by dropping the assertion. FreeBSD-issue: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252700 Signed-off-by: Rob Wing Sponsored-by: rsync.net Sponsored-by: Klara, Inc. --- module/os/freebsd/zfs/zfs_ctldir.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/module/os/freebsd/zfs/zfs_ctldir.c b/module/os/freebsd/zfs/zfs_ctldir.c index 42bb7551e9c7..ca2f4419d1c4 100644 --- a/module/os/freebsd/zfs/zfs_ctldir.c +++ b/module/os/freebsd/zfs/zfs_ctldir.c @@ -1153,7 +1153,7 @@ zfsctl_snapshot_inactive(struct vop_inactive_args *ap) { vnode_t *vp = ap->a_vp; - VERIFY3S(vrecycle(vp), ==, 1); + vrecycle(vp); return (0); } @@ -1237,6 +1237,8 @@ static struct vop_vector zfsctl_ops_snapshot = { #if __FreeBSD_version >= 1300121 .vop_fplookup_vexec = VOP_EAGAIN, #endif + .vop_open = zfsctl_common_open, + .vop_close = zfsctl_common_close, .vop_inactive = zfsctl_snapshot_inactive, #if __FreeBSD_version >= 1300045 .vop_need_inactive = vop_stdneed_inactive,