diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2019-05-05 11:20:43 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2019-05-05 11:20:43 +0000 |
commit | 78022527bb7aad6015ea88102562ad6ede2752fa (patch) | |
tree | aa5f2c3500763d961ae6e99d0d1ef55d30dd62de /sys/fs/deadfs | |
parent | 7f1446052fd7ff1006f9a98a76f8b1010e4e413e (diff) | |
download | src-78022527bb7aad6015ea88102562ad6ede2752fa.tar.gz src-78022527bb7aad6015ea88102562ad6ede2752fa.zip |
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
Notes
Notes:
svn path=/head/; revision=347151
Diffstat (limited to 'sys/fs/deadfs')
-rw-r--r-- | sys/fs/deadfs/dead_vnops.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c index aa2e3f8f6585..a3153aed326a 100644 --- a/sys/fs/deadfs/dead_vnops.c +++ b/sys/fs/deadfs/dead_vnops.c @@ -47,6 +47,7 @@ static vop_lookup_t dead_lookup; static vop_open_t dead_open; static vop_getwritemount_t dead_getwritemount; static vop_rename_t dead_rename; +static vop_unset_text_t dead_unset_text; struct vop_vector dead_vnodeops = { .vop_default = &default_vnodeops, @@ -76,6 +77,7 @@ struct vop_vector dead_vnodeops = { .vop_setattr = VOP_EBADF, .vop_symlink = VOP_PANIC, .vop_vptocnp = VOP_EBADF, + .vop_unset_text = dead_unset_text, .vop_write = dead_write, }; @@ -148,3 +150,10 @@ dead_rename(struct vop_rename_args *ap) vop_rename_fail(ap); return (EXDEV); } + +static int +dead_unset_text(struct vop_unset_text_args *ap) +{ + + return (0); +} |