aboutsummaryrefslogtreecommitdiff
path: root/sys/vm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_fault.c7
-rw-r--r--sys/vm/vm_object.h1
-rw-r--r--sys/vm/vnode_pager.c6
3 files changed, 13 insertions, 1 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 23978132f43f..80f9c384ed93 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -887,6 +887,13 @@ RetryFault_oom:
*/
if (fs.object->type != OBJT_DEFAULT ||
fs.object == fs.first_object) {
+ if ((fs.object->flags & OBJ_SIZEVNLOCK) != 0) {
+ rv = vm_fault_lock_vnode(&fs);
+ MPASS(rv == KERN_SUCCESS ||
+ rv == KERN_RESOURCE_SHORTAGE);
+ if (rv == KERN_RESOURCE_SHORTAGE)
+ goto RetryFault;
+ }
if (fs.pindex >= fs.object->size) {
unlock_and_deallocate(&fs);
return (KERN_OUT_OF_BOUNDS);
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index f5aac8bb74a6..9a08dee6e00b 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -186,6 +186,7 @@ struct vm_object {
#define OBJ_DEAD 0x0008 /* dead objects (during rundown) */
#define OBJ_NOSPLIT 0x0010 /* dont split this object */
#define OBJ_UMTXDEAD 0x0020 /* umtx pshared was terminated */
+#define OBJ_SIZEVNLOCK 0x0040 /* lock vnode to check obj size */
#define OBJ_PG_DTOR 0x0080 /* dont reset object, leave that for dtor */
#define OBJ_MIGHTBEDIRTY 0x0100 /* object might be dirty, only for vnode */
#define OBJ_TMPFS_NODE 0x0200 /* object belongs to tmpfs VREG node */
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index f19c3a0af3f0..d9d14896051d 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -269,8 +269,12 @@ retry:
object->un_pager.vnp.vnp_size = size;
object->un_pager.vnp.writemappings = 0;
object->domain.dr_policy = vnode_domainset;
-
object->handle = handle;
+ if ((vp->v_vflag & VV_VMSIZEVNLOCK) != 0) {
+ VM_OBJECT_WLOCK(object);
+ vm_object_set_flag(object, OBJ_SIZEVNLOCK);
+ VM_OBJECT_WUNLOCK(object);
+ }
VI_LOCK(vp);
if (vp->v_object != NULL) {
/*