From bb9e2184f09f42be6af82f28a50fe1914c670c32 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 18 Aug 2019 20:24:52 +0000 Subject: [PATCH] Change locking requirements for VOP_UNSET_TEXT(). Require the vnode to be locked for the VOP_UNSET_TEXT() call. This will be used by the following bug fix for a tmpfs issue. Tested by: sbruno, pho (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/compat/linux/linux_misc.c | 7 ++++++- sys/kern/vnode_if.src | 2 +- sys/vm/vm_map.c | 14 +++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index df2989f15be2..ed2d0701af5c 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -472,8 +472,13 @@ cleanup: locked = false; VOP_CLOSE(vp, FREAD, td->td_ucred, td); } - if (textset) + if (textset) { + if (!locked) { + locked = true; + VOP_LOCK(vp, LK_SHARED | LK_RETRY); + } VOP_UNSET_TEXT_CHECKED(vp); + } if (locked) VOP_UNLOCK(vp, 0); diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index dc0c08424ca9..576a1487e1c6 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -695,7 +695,7 @@ vop_set_text { }; -%% vop_unset_text vp = = = +%% vop_unset_text vp L L L vop_unset_text { IN struct vnode *vp; diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index ad66e2d4a97b..6b37418777df 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -547,12 +547,20 @@ vm_map_entry_set_vnode_text(vm_map_entry_t entry, bool add) "entry %p, object %p, add %d", entry, object, add)); } if (vp != NULL) { - if (add) + if (add) { VOP_SET_TEXT_CHECKED(vp); - else + VM_OBJECT_RUNLOCK(object); + } else { + vhold(vp); + VM_OBJECT_RUNLOCK(object); + vn_lock(vp, LK_SHARED | LK_RETRY); VOP_UNSET_TEXT_CHECKED(vp); + VOP_UNLOCK(vp, 0); + vdrop(vp); + } + } else { + VM_OBJECT_RUNLOCK(object); } - VM_OBJECT_RUNLOCK(object); } static void