Print this page
5384 pvn_getpages may assert in valid scenarios
*** 18,27 ****
--- 18,28 ----
*
* 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,1101 ****
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.
*/
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 *),
--- 1089,1100 ----
MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)));
(void) segmap_release(segkmap, addr, SM_WRITE | SM_ASYNC);
}
/*
! * 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,1123 ****
page_t **ppp;
u_offset_t o, eoff;
size_t sz, xlen;
int err;
! ASSERT(plsz >= len); /* insure that we have enough space */
/*
* 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
--- 1112,1123 ----
page_t **ppp;
u_offset_t o, eoff;
size_t sz, xlen;
int err;
! /* 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,1141 ****
* 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;
eoff = off + len;
xlen = len;
for (o = off; o < eoff; o += PAGESIZE, addr += PAGESIZE,
xlen -= PAGESIZE) {
! if (o + PAGESIZE >= eoff) {
/*
* Last time through - allow the all of
* what's left of the pl[] array to be used.
*/
sz = plsz - (o - off);
--- 1126,1141 ----
* 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 = (pl != NULL) ? PAGESIZE : 0;
eoff = off + len;
xlen = len;
for (o = off; o < eoff; o += PAGESIZE, addr += PAGESIZE,
xlen -= PAGESIZE) {
! 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);