]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Switch to use shared vnode locks for text files during image activation.
authorkib <kib@FreeBSD.org>
Sun, 5 May 2019 11:20:43 +0000 (11:20 +0000)
committerkib <kib@FreeBSD.org>
Sun, 5 May 2019 11:20:43 +0000 (11:20 +0000)
commit2dc0d9edaa7487c11806a0ea8cae77e3a4a79785
treeaa5f2c3500763d961ae6e99d0d1ef55d30dd62de
parentce1a272ee3e3b26510dfcc51ec2c8f183eabf131
Switch to use shared vnode locks for text files during image activation.

kern_execve() locks text vnode exclusive to be able to set and clear
VV_TEXT flag. VV_TEXT is mutually exclusive with the v_writecount > 0
condition.

The change removes VV_TEXT, replacing it with the condition
v_writecount <= -1, and puts v_writecount under the vnode interlock.
Each text reference decrements v_writecount.  To clear the text
reference when the segment is unmapped, it is recorded in the
vm_map_entry backed by the text file as MAP_ENTRY_VN_TEXT flag, and
v_writecount is incremented on the map entry removal

The operations like VOP_ADD_WRITECOUNT() and VOP_SET_TEXT() check that
v_writecount does not contradict the desired change.  vn_writecheck()
is now racy and its use was eliminated everywhere except access.
Atomic check for writeability and increment of v_writecount is
performed by the VOP.  vn_truncate() now increments v_writecount
around VOP_SETATTR() call, lack of which is arguably a bug on its own.

nullfs bypasses v_writecount to the lower vnode always, so nullfs
vnode has its own v_writecount correct, and lower vnode gets all
references, since object->handle is always lower vnode.

On the text vnode' vm object dealloc, the v_writecount value is reset
to zero, and deadfs vop_unset_text short-circuit the operation.
Reclamation of lowervp always reclaims all nullfs vnodes referencing
lowervp first, so no stray references are left.

Reviewed by: markj, trasz
Tested by: mjg, pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 month
Differential revision: https://reviews.freebsd.org/D19923
23 files changed:
libexec/rtld-elf/rtld.c
sys/compat/linux/linux_misc.c
sys/fs/deadfs/dead_vnops.c
sys/fs/nfsclient/nfs_clbio.c
sys/fs/nfsclient/nfs_clvnops.c
sys/fs/nullfs/null_vnops.c
sys/fs/unionfs/union_subr.c
sys/kern/imgact_aout.c
sys/kern/imgact_elf.c
sys/kern/kern_exec.c
sys/kern/vfs_default.c
sys/kern/vfs_subr.c
sys/kern/vfs_vnops.c
sys/kern/vnode_if.src
sys/sys/imgact.h
sys/sys/vnode.h
sys/ufs/ufs/ufs_extattr.c
sys/vm/vm_fault.c
sys/vm/vm_map.c
sys/vm/vm_map.h
sys/vm/vm_mmap.c
sys/vm/vm_object.c
sys/vm/vnode_pager.c