Print this page
5384 pvn_getpages may assert in valid scenarios

@@ -18,10 +18,11 @@
  *
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  */
 
 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
 /*        All Rights Reserved   */
 

@@ -1088,14 +1089,12 @@
             MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)));
         (void) segmap_release(segkmap, addr, SM_WRITE | SM_ASYNC);
 }
 
 /*
- * Handles common work of the VOP_GETPAGE routines when more than
- * one page must be returned by calling a file system specific operation
- * to do most of the work.  Must be called with the vp already locked
- * by the VOP_GETPAGE routine.
+ * Handles common work of the VOP_GETPAGE routines by iterating page by page
+ * calling the getpage helper for each.
  */
 int
 pvn_getpages(
         int (*getpage)(vnode_t *, u_offset_t, size_t, uint_t *, page_t *[],
                 size_t, struct seg *, caddr_t, enum seg_rw, cred_t *),

@@ -1113,11 +1112,12 @@
         page_t **ppp;
         u_offset_t o, eoff;
         size_t sz, xlen;
         int err;
 
-        ASSERT(plsz >= len);            /* insure that we have enough space */
+        /* ensure that we have enough space */
+        ASSERT(pl == NULL || plsz >= len);
 
         /*
          * Loop one page at a time and let getapage function fill
          * in the next page in array.  We only allow one page to be
          * returned at a time (except for the last page) so that we

@@ -1126,16 +1126,16 @@
          * but it does the job correctly.  We hope that the cost of a
          * getapage call for a resident page that we might have been
          * able to get from an earlier call doesn't cost too much.
          */
         ppp = pl;
-        sz = PAGESIZE;
+        sz = (pl != NULL) ? PAGESIZE : 0;
         eoff = off + len;
         xlen = len;
         for (o = off; o < eoff; o += PAGESIZE, addr += PAGESIZE,
             xlen -= PAGESIZE) {
-                if (o + PAGESIZE >= eoff) {
+                if (o + PAGESIZE >= eoff && pl != NULL) {
                         /*
                          * Last time through - allow the all of
                          * what's left of the pl[] array to be used.
                          */
                         sz = plsz - (o - off);