aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/deadfs
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2019-05-05 11:20:43 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2019-05-05 11:20:43 +0000
commit78022527bb7aad6015ea88102562ad6ede2752fa (patch)
treeaa5f2c3500763d961ae6e99d0d1ef55d30dd62de /sys/fs/deadfs
parent7f1446052fd7ff1006f9a98a76f8b1010e4e413e (diff)
downloadsrc-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.c9
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);
+}