78022527bb
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 |
||
---|---|---|
.. | ||
check_error.d | ||
check_internal_locks.d | ||
linux_common.c | ||
linux_common.h | ||
linux_dtrace.h | ||
linux_emul.c | ||
linux_emul.h | ||
linux_errno.c | ||
linux_errno.inc | ||
linux_event.c | ||
linux_event.h | ||
linux_file.c | ||
linux_file.h | ||
linux_fork.c | ||
linux_futex.c | ||
linux_futex.h | ||
linux_getcwd.c | ||
linux_ioctl.c | ||
linux_ioctl.h | ||
linux_ipc64.h | ||
linux_ipc.c | ||
linux_ipc.h | ||
linux_mib.c | ||
linux_mib.h | ||
linux_misc.c | ||
linux_misc.h | ||
linux_mmap.c | ||
linux_mmap.h | ||
linux_persona.h | ||
linux_signal.c | ||
linux_signal.h | ||
linux_socket.c | ||
linux_socket.h | ||
linux_stats.c | ||
linux_sysctl.c | ||
linux_sysproto.h | ||
linux_time.c | ||
linux_timer.c | ||
linux_timer.h | ||
linux_uid16.c | ||
linux_util.c | ||
linux_util.h | ||
linux_vdso.c | ||
linux_vdso.h | ||
linux_videodev2_compat.h | ||
linux_videodev_compat.h | ||
linux.c | ||
linux.h | ||
stats_timing.d | ||
trace_futexes.d |