diff options
author | kib <kib@FreeBSD.org> | 2012-11-02 13:56:36 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-11-02 13:56:36 +0000 |
commit | f16ea990070abd8c9cb42bfc7001ada604b4df01 (patch) | |
tree | 77eb9f8e9de108d0ae7792cfceedcd340198177e /sys/vm | |
parent | 37f3bd87e4ec81bcec505485b1cf96c74db846f0 (diff) | |
download | FreeBSD-src-f16ea990070abd8c9cb42bfc7001ada604b4df01.zip FreeBSD-src-f16ea990070abd8c9cb42bfc7001ada604b4df01.tar.gz |
The r241025 fixed the case when a binary, executed from nullfs mount,
was still possible to open for write from the lower filesystem. There
is a symmetric situation where the binary could already has file
descriptors opened for write, but it can be executed from the nullfs
overlay.
Handle the issue by passing one v_writecount reference to the lower
vnode if nullfs vnode has non-zero v_writecount. Note that only one
write reference can be donated, since nullfs only keeps one use
reference on the lower vnode. Always use the lower vnode v_writecount
for the checks.
Introduce the VOP_GET_WRITECOUNT to read v_writecount, which is
currently always bypassed to the lower vnode, and VOP_ADD_WRITECOUNT
to manipulate the v_writecount value, which manages a single bypass
reference to the lower vnode. Caling the VOPs instead of directly
accessing v_writecount provide the fix described in the previous
paragraph.
Tested by: pho
MFC after: 3 weeks
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vnode_pager.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index f6848b6..a6d78f4 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -272,7 +272,7 @@ vnode_pager_dealloc(object) ASSERT_VOP_ELOCKED(vp, "vnode_pager_dealloc"); if (object->un_pager.vnp.writemappings > 0) { object->un_pager.vnp.writemappings = 0; - vp->v_writecount--; + VOP_ADD_WRITECOUNT(vp, -1); CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", __func__, vp, vp->v_writecount); } @@ -1212,12 +1212,12 @@ vnode_pager_update_writecount(vm_object_t object, vm_offset_t start, vp = object->handle; if (old_wm == 0 && object->un_pager.vnp.writemappings != 0) { ASSERT_VOP_ELOCKED(vp, "v_writecount inc"); - vp->v_writecount++; + VOP_ADD_WRITECOUNT(vp, 1); CTR3(KTR_VFS, "%s: vp %p v_writecount increased to %d", __func__, vp, vp->v_writecount); } else if (old_wm != 0 && object->un_pager.vnp.writemappings == 0) { ASSERT_VOP_ELOCKED(vp, "v_writecount dec"); - vp->v_writecount--; + VOP_ADD_WRITECOUNT(vp, -1); CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", __func__, vp, vp->v_writecount); } |