From 90603601b439a800f0458d9d7e7ed8c390aa8668 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 23 Nov 2024 17:26:52 -0500 Subject: [PATCH] FreeBSD: Lock vnode in zfs_ioctl() Previously vnode was not locked there, unlike Linux. It required locking it in vn_flush_cached_data(), which recursed on the lock if called from zfs_clone_range(), having the vnode locked. Reviewed-by: Alan Somers Reviewed-by: Brian Behlendorf Signed-off-by: Alexander Motin Sponsored by: iXsystems, Inc. Closes #16789 Closes #16796 --- include/os/freebsd/spl/sys/vnode.h | 4 ---- module/os/freebsd/zfs/zfs_vnops_os.c | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/os/freebsd/spl/sys/vnode.h b/include/os/freebsd/spl/sys/vnode.h index 76ea3eff3792..10cb3663d4fb 100644 --- a/include/os/freebsd/spl/sys/vnode.h +++ b/include/os/freebsd/spl/sys/vnode.h @@ -91,20 +91,16 @@ vn_is_readonly(vnode_t *vp) ((vp)->v_object != NULL && \ (vp)->v_object->resident_page_count > 0) -#ifndef IN_BASE static __inline void vn_flush_cached_data(vnode_t *vp, boolean_t sync) { if (vm_object_mightbedirty(vp->v_object)) { int flags = sync ? OBJPC_SYNC : 0; - vn_lock(vp, LK_SHARED | LK_RETRY); zfs_vmobject_wlock(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, flags); zfs_vmobject_wunlock(vp->v_object); - VOP_UNLOCK(vp); } } -#endif #define vn_exists(vp) do { } while (0) #define vn_invalid(vp) do { } while (0) diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index e5acd684ee6b..95a947e3d7d2 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -291,8 +291,12 @@ zfs_ioctl(vnode_t *vp, ulong_t com, intptr_t data, int flag, cred_t *cred, case F_SEEK_HOLE: { off = *(offset_t *)data; + error = vn_lock(vp, LK_SHARED); + if (error) + return (error); /* offset parameter is in/out */ error = zfs_holey(VTOZ(vp), com, &off); + VOP_UNLOCK(vp); if (error) return (error); *(offset_t *)data = off;