3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27
28 /*
29 * University Copyright- Copyright (c) 1982, 1986, 1988
30 * The Regents of the University of California
31 * All Rights Reserved
32 *
33 * University Acknowledgment- Portions of this document are derived from
34 * software developed by the University of California, Berkeley, and its
35 * contributors.
36 */
37
38 /*
39 * VM - paged vnode.
40 *
41 * This file supplies vm support for the vnode operations that deal with pages.
42 */
1073 * dirty so that we know that when this page is written
1074 * back, the zeroed information will go out with it. If
1075 * the page is not currently in memory, then the kzero
1076 * operation will cause it to be brought it. We use kzero
1077 * instead of bzero so that if the page cannot be read in
1078 * for any reason, the system will not panic. We need
1079 * to zero out a minimum of the fs given zbytes, but we
1080 * might also have to do more to get the entire last page.
1081 */
1082
1083 if ((zbytes + (vplen & MAXBOFFSET)) > MAXBSIZE)
1084 panic("pvn_vptrunc zbytes");
1085 addr = segmap_getmapflt(segkmap, vp, vplen,
1086 MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)), 1, S_WRITE);
1087 (void) kzero(addr + (vplen & MAXBOFFSET),
1088 MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)));
1089 (void) segmap_release(segkmap, addr, SM_WRITE | SM_ASYNC);
1090 }
1091
1092 /*
1093 * Handles common work of the VOP_GETPAGE routines when more than
1094 * one page must be returned by calling a file system specific operation
1095 * to do most of the work. Must be called with the vp already locked
1096 * by the VOP_GETPAGE routine.
1097 */
1098 int
1099 pvn_getpages(
1100 int (*getpage)(vnode_t *, u_offset_t, size_t, uint_t *, page_t *[],
1101 size_t, struct seg *, caddr_t, enum seg_rw, cred_t *),
1102 struct vnode *vp,
1103 u_offset_t off,
1104 size_t len,
1105 uint_t *protp,
1106 page_t *pl[],
1107 size_t plsz,
1108 struct seg *seg,
1109 caddr_t addr,
1110 enum seg_rw rw,
1111 struct cred *cred)
1112 {
1113 page_t **ppp;
1114 u_offset_t o, eoff;
1115 size_t sz, xlen;
1116 int err;
1117
1118 ASSERT(plsz >= len); /* insure that we have enough space */
1119
1120 /*
1121 * Loop one page at a time and let getapage function fill
1122 * in the next page in array. We only allow one page to be
1123 * returned at a time (except for the last page) so that we
1124 * don't have any problems with duplicates and other such
1125 * painful problems. This is a very simple minded algorithm,
1126 * but it does the job correctly. We hope that the cost of a
1127 * getapage call for a resident page that we might have been
1128 * able to get from an earlier call doesn't cost too much.
1129 */
1130 ppp = pl;
1131 sz = PAGESIZE;
1132 eoff = off + len;
1133 xlen = len;
1134 for (o = off; o < eoff; o += PAGESIZE, addr += PAGESIZE,
1135 xlen -= PAGESIZE) {
1136 if (o + PAGESIZE >= eoff) {
1137 /*
1138 * Last time through - allow the all of
1139 * what's left of the pl[] array to be used.
1140 */
1141 sz = plsz - (o - off);
1142 }
1143 err = (*getpage)(vp, o, xlen, protp, ppp, sz, seg, addr,
1144 rw, cred);
1145 if (err) {
1146 /*
1147 * Release any pages we already got.
1148 */
1149 if (o > off && pl != NULL) {
1150 for (ppp = pl; *ppp != NULL; *ppp++ = NULL)
1151 (void) page_release(*ppp, 1);
1152 }
1153 break;
1154 }
1155 if (pl != NULL)
1156 ppp++;
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 /*
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
32 * All Rights Reserved
33 *
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
36 * contributors.
37 */
38
39 /*
40 * VM - paged vnode.
41 *
42 * This file supplies vm support for the vnode operations that deal with pages.
43 */
1074 * dirty so that we know that when this page is written
1075 * back, the zeroed information will go out with it. If
1076 * the page is not currently in memory, then the kzero
1077 * operation will cause it to be brought it. We use kzero
1078 * instead of bzero so that if the page cannot be read in
1079 * for any reason, the system will not panic. We need
1080 * to zero out a minimum of the fs given zbytes, but we
1081 * might also have to do more to get the entire last page.
1082 */
1083
1084 if ((zbytes + (vplen & MAXBOFFSET)) > MAXBSIZE)
1085 panic("pvn_vptrunc zbytes");
1086 addr = segmap_getmapflt(segkmap, vp, vplen,
1087 MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)), 1, S_WRITE);
1088 (void) kzero(addr + (vplen & MAXBOFFSET),
1089 MAX(zbytes, PAGESIZE - (vplen & PAGEOFFSET)));
1090 (void) segmap_release(segkmap, addr, SM_WRITE | SM_ASYNC);
1091 }
1092
1093 /*
1094 * Handles common work of the VOP_GETPAGE routines by iterating page by page
1095 * calling the getpage helper for each.
1096 */
1097 int
1098 pvn_getpages(
1099 int (*getpage)(vnode_t *, u_offset_t, size_t, uint_t *, page_t *[],
1100 size_t, struct seg *, caddr_t, enum seg_rw, cred_t *),
1101 struct vnode *vp,
1102 u_offset_t off,
1103 size_t len,
1104 uint_t *protp,
1105 page_t *pl[],
1106 size_t plsz,
1107 struct seg *seg,
1108 caddr_t addr,
1109 enum seg_rw rw,
1110 struct cred *cred)
1111 {
1112 page_t **ppp;
1113 u_offset_t o, eoff;
1114 size_t sz, xlen;
1115 int err;
1116
1117 /* ensure that we have enough space */
1118 ASSERT(pl == NULL || plsz >= len);
1119
1120 /*
1121 * Loop one page at a time and let getapage function fill
1122 * in the next page in array. We only allow one page to be
1123 * returned at a time (except for the last page) so that we
1124 * don't have any problems with duplicates and other such
1125 * painful problems. This is a very simple minded algorithm,
1126 * but it does the job correctly. We hope that the cost of a
1127 * getapage call for a resident page that we might have been
1128 * able to get from an earlier call doesn't cost too much.
1129 */
1130 ppp = pl;
1131 sz = (pl != NULL) ? PAGESIZE : 0;
1132 eoff = off + len;
1133 xlen = len;
1134 for (o = off; o < eoff; o += PAGESIZE, addr += PAGESIZE,
1135 xlen -= PAGESIZE) {
1136 if (o + PAGESIZE >= eoff && pl != NULL) {
1137 /*
1138 * Last time through - allow the all of
1139 * what's left of the pl[] array to be used.
1140 */
1141 sz = plsz - (o - off);
1142 }
1143 err = (*getpage)(vp, o, xlen, protp, ppp, sz, seg, addr,
1144 rw, cred);
1145 if (err) {
1146 /*
1147 * Release any pages we already got.
1148 */
1149 if (o > off && pl != NULL) {
1150 for (ppp = pl; *ppp != NULL; *ppp++ = NULL)
1151 (void) page_release(*ppp, 1);
1152 }
1153 break;
1154 }
1155 if (pl != NULL)
1156 ppp++;
|