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) {
                        /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to