Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Oct 2019 16:09:26 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r353890 - in head/sys: sys vm
Message-ID:  <201910221609.x9MG9Q4x053420@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Oct 22 16:09:25 2019
New Revision: 353890
URL: https://svnweb.freebsd.org/changeset/base/353890

Log:
  Add VV_VMSIZEVNLOCK flag.
  
  The flag specifies that vm_fault() handler should check the vnode'
  vm_object size under the vnode lock.  It is converted into the object'
  OBJ_SIZEVNLOCK flag in vnode_pager_alloc().
  
  Tested by:	pho
  Reviewed by:	markj
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D21883

Modified:
  head/sys/sys/vnode.h
  head/sys/vm/vm_fault.c
  head/sys/vm/vm_object.h
  head/sys/vm/vnode_pager.c

Modified: head/sys/sys/vnode.h
==============================================================================
--- head/sys/sys/vnode.h	Tue Oct 22 16:06:33 2019	(r353889)
+++ head/sys/sys/vnode.h	Tue Oct 22 16:09:25 2019	(r353890)
@@ -247,6 +247,7 @@ struct xvnode {
 #define	VV_NOSYNC	0x0004	/* unlinked, stop syncing */
 #define	VV_ETERNALDEV	0x0008	/* device that is never destroyed */
 #define	VV_CACHEDLABEL	0x0010	/* Vnode has valid cached MAC label */
+#define	VV_VMSIZEVNLOCK	0x0020	/* object size check requires vnode lock */
 #define	VV_COPYONWRITE	0x0040	/* vnode is doing copy-on-write */
 #define	VV_SYSTEM	0x0080	/* vnode being used by kernel */
 #define	VV_PROCDEP	0x0100	/* vnode is process dependent */

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c	Tue Oct 22 16:06:33 2019	(r353889)
+++ head/sys/vm/vm_fault.c	Tue Oct 22 16:09:25 2019	(r353890)
@@ -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);

Modified: head/sys/vm/vm_object.h
==============================================================================
--- head/sys/vm/vm_object.h	Tue Oct 22 16:06:33 2019	(r353889)
+++ head/sys/vm/vm_object.h	Tue Oct 22 16:09:25 2019	(r353890)
@@ -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 */

Modified: head/sys/vm/vnode_pager.c
==============================================================================
--- head/sys/vm/vnode_pager.c	Tue Oct 22 16:06:33 2019	(r353889)
+++ head/sys/vm/vnode_pager.c	Tue Oct 22 16:09:25 2019	(r353890)
@@ -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) {
 			/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910221609.x9MG9Q4x053420>