xref: /onnv-gate/usr/src/uts/common/avs/ns/nsctl/nsc_cache.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM #include <sys/types.h>
27*7836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
28*7836SJohn.Forte@Sun.COM #include <sys/errno.h>
29*7836SJohn.Forte@Sun.COM #include <sys/uio.h>
30*7836SJohn.Forte@Sun.COM #include <sys/ddi.h>
31*7836SJohn.Forte@Sun.COM 
32*7836SJohn.Forte@Sun.COM #define	__NSC_GEN__
33*7836SJohn.Forte@Sun.COM #include "nsc_dev.h"
34*7836SJohn.Forte@Sun.COM 
35*7836SJohn.Forte@Sun.COM #ifdef DS_DDICT
36*7836SJohn.Forte@Sun.COM #include "../contract.h"
37*7836SJohn.Forte@Sun.COM #endif
38*7836SJohn.Forte@Sun.COM 
39*7836SJohn.Forte@Sun.COM #include "../nsctl.h"
40*7836SJohn.Forte@Sun.COM 
41*7836SJohn.Forte@Sun.COM 
42*7836SJohn.Forte@Sun.COM #define	_I(x)	(((long)(&((nsc_io_t *)0)->x))/sizeof (long))
43*7836SJohn.Forte@Sun.COM 
44*7836SJohn.Forte@Sun.COM 
45*7836SJohn.Forte@Sun.COM nsc_def_t _nsc_cache_def[] = {
46*7836SJohn.Forte@Sun.COM 	"AllocBuf",	(uintptr_t)nsc_ioerr,	_I(alloc_buf),
47*7836SJohn.Forte@Sun.COM 	"FreeBuf",	(uintptr_t)nsc_fatal,	_I(free_buf),
48*7836SJohn.Forte@Sun.COM 	"Read",		(uintptr_t)nsc_fatal,	_I(read),
49*7836SJohn.Forte@Sun.COM 	"Write",	(uintptr_t)nsc_fatal,	_I(write),
50*7836SJohn.Forte@Sun.COM 	"Zero",		(uintptr_t)nsc_fatal,	_I(zero),
51*7836SJohn.Forte@Sun.COM 	"Copy",		(uintptr_t)nsc_ioerr,	_I(copy),
52*7836SJohn.Forte@Sun.COM 	"CopyDirect",	(uintptr_t)nsc_ioerr,	_I(copy_direct),
53*7836SJohn.Forte@Sun.COM 	"Uncommit",	(uintptr_t)nsc_null,	_I(uncommit),
54*7836SJohn.Forte@Sun.COM 	"AllocHandle",	(uintptr_t)nsc_null,	_I(alloc_h),
55*7836SJohn.Forte@Sun.COM 	"FreeHandle",	(uintptr_t)nsc_fatal,	_I(free_h),
56*7836SJohn.Forte@Sun.COM 	"TrackSize",	(uintptr_t)nsc_null,	_I(trksize),
57*7836SJohn.Forte@Sun.COM 	"Discard",	(uintptr_t)nsc_null,	_I(discard),
58*7836SJohn.Forte@Sun.COM 	"Sizes",	(uintptr_t)nsc_null,	_I(sizes),
59*7836SJohn.Forte@Sun.COM 	"GetPinned",	(uintptr_t)nsc_null,	_I(getpin),
60*7836SJohn.Forte@Sun.COM 	"NodeHints",	(uintptr_t)nsc_inval,	_I(nodehints),
61*7836SJohn.Forte@Sun.COM 	0,		0,		0
62*7836SJohn.Forte@Sun.COM };
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM 
65*7836SJohn.Forte@Sun.COM static int _nsc_alloc_buf_h(blind_t, nsc_off_t, nsc_size_t, int,
66*7836SJohn.Forte@Sun.COM     nsc_buf_t **, nsc_fd_t *);
67*7836SJohn.Forte@Sun.COM static int _nsc_copy_h(nsc_buf_t *, nsc_buf_t *, nsc_off_t,
68*7836SJohn.Forte@Sun.COM     nsc_off_t, nsc_size_t);
69*7836SJohn.Forte@Sun.COM 
70*7836SJohn.Forte@Sun.COM extern nsc_io_t *_nsc_reserve_io(char *, int);
71*7836SJohn.Forte@Sun.COM extern void _nsc_release_io(nsc_io_t *);
72*7836SJohn.Forte@Sun.COM 
73*7836SJohn.Forte@Sun.COM extern kmutex_t _nsc_io_lock;
74*7836SJohn.Forte@Sun.COM 
75*7836SJohn.Forte@Sun.COM 
76*7836SJohn.Forte@Sun.COM 
77*7836SJohn.Forte@Sun.COM 
78*7836SJohn.Forte@Sun.COM /* ARGSUSED */
79*7836SJohn.Forte@Sun.COM 
80*7836SJohn.Forte@Sun.COM void
_nsc_add_cache(nsc_io_t * io)81*7836SJohn.Forte@Sun.COM _nsc_add_cache(nsc_io_t *io)
82*7836SJohn.Forte@Sun.COM {
83*7836SJohn.Forte@Sun.COM }
84*7836SJohn.Forte@Sun.COM 
85*7836SJohn.Forte@Sun.COM 
86*7836SJohn.Forte@Sun.COM nsc_buf_t *
nsc_alloc_handle(nsc_fd_t * fd,void (* d_cb)(),void (* r_cb)(),void (* w_cb)())87*7836SJohn.Forte@Sun.COM nsc_alloc_handle(nsc_fd_t *fd, void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
88*7836SJohn.Forte@Sun.COM {
89*7836SJohn.Forte@Sun.COM 	nsc_buf_t *h = (*fd->sf_aio->alloc_h)(d_cb, r_cb, w_cb, fd->sf_cd);
90*7836SJohn.Forte@Sun.COM 
91*7836SJohn.Forte@Sun.COM 	if (h)
92*7836SJohn.Forte@Sun.COM 		h->sb_fd = fd;
93*7836SJohn.Forte@Sun.COM 
94*7836SJohn.Forte@Sun.COM 	return (h);
95*7836SJohn.Forte@Sun.COM }
96*7836SJohn.Forte@Sun.COM 
97*7836SJohn.Forte@Sun.COM 
98*7836SJohn.Forte@Sun.COM int
nsc_free_handle(nsc_buf_t * h)99*7836SJohn.Forte@Sun.COM nsc_free_handle(nsc_buf_t *h)
100*7836SJohn.Forte@Sun.COM {
101*7836SJohn.Forte@Sun.COM 	if (h == NULL || (h->sb_flag & NSC_ABUF))
102*7836SJohn.Forte@Sun.COM 		return (EINVAL);
103*7836SJohn.Forte@Sun.COM 
104*7836SJohn.Forte@Sun.COM 	return ((*h->sb_fd->sf_aio->free_h)(h, h->sb_fd->sf_cd));
105*7836SJohn.Forte@Sun.COM }
106*7836SJohn.Forte@Sun.COM 
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM int
nsc_alloc_abuf(nsc_off_t pos,nsc_size_t len,int flag,nsc_buf_t ** ptr)109*7836SJohn.Forte@Sun.COM nsc_alloc_abuf(nsc_off_t pos, nsc_size_t len, int flag, nsc_buf_t **ptr)
110*7836SJohn.Forte@Sun.COM {
111*7836SJohn.Forte@Sun.COM 	nsc_buf_t *h;
112*7836SJohn.Forte@Sun.COM 	nsc_io_t *io;
113*7836SJohn.Forte@Sun.COM 	int rc;
114*7836SJohn.Forte@Sun.COM 
115*7836SJohn.Forte@Sun.COM 	if (*ptr != NULL)
116*7836SJohn.Forte@Sun.COM 		return (EINVAL);
117*7836SJohn.Forte@Sun.COM 
118*7836SJohn.Forte@Sun.COM 	if (flag & NSC_NODATA)
119*7836SJohn.Forte@Sun.COM 		return (EINVAL);
120*7836SJohn.Forte@Sun.COM 
121*7836SJohn.Forte@Sun.COM 	io = _nsc_reserve_io(NULL, NSC_ANON);
122*7836SJohn.Forte@Sun.COM 	if (io == NULL)
123*7836SJohn.Forte@Sun.COM 		return (ENOBUFS);
124*7836SJohn.Forte@Sun.COM 
125*7836SJohn.Forte@Sun.COM 	if ((h = (*io->alloc_h)(NULL, NULL, NULL, NSC_ANON_CD)) == NULL) {
126*7836SJohn.Forte@Sun.COM 		_nsc_release_io(io);
127*7836SJohn.Forte@Sun.COM 		return (ENOBUFS);
128*7836SJohn.Forte@Sun.COM 	}
129*7836SJohn.Forte@Sun.COM 
130*7836SJohn.Forte@Sun.COM 	rc = (*io->alloc_buf)(NSC_ANON_CD, pos, len,
131*7836SJohn.Forte@Sun.COM 	    NSC_NOCACHE|flag, &h, NULL);
132*7836SJohn.Forte@Sun.COM 	if (rc <= 0) {
133*7836SJohn.Forte@Sun.COM 		h->sb_flag &= ~NSC_HALLOCATED;
134*7836SJohn.Forte@Sun.COM 		h->sb_flag |= NSC_ABUF;
135*7836SJohn.Forte@Sun.COM 		h->sb_fd = (nsc_fd_t *)io;	/* note overloaded field */
136*7836SJohn.Forte@Sun.COM 
137*7836SJohn.Forte@Sun.COM 		*ptr = h;
138*7836SJohn.Forte@Sun.COM 
139*7836SJohn.Forte@Sun.COM 		mutex_enter(&_nsc_io_lock);
140*7836SJohn.Forte@Sun.COM 		io->abufcnt++;
141*7836SJohn.Forte@Sun.COM 		mutex_exit(&_nsc_io_lock);
142*7836SJohn.Forte@Sun.COM 	}
143*7836SJohn.Forte@Sun.COM 
144*7836SJohn.Forte@Sun.COM 	_nsc_release_io(io);
145*7836SJohn.Forte@Sun.COM 	return (rc);
146*7836SJohn.Forte@Sun.COM }
147*7836SJohn.Forte@Sun.COM 
148*7836SJohn.Forte@Sun.COM 
149*7836SJohn.Forte@Sun.COM int
nsc_alloc_buf(nsc_fd_t * fd,nsc_off_t pos,nsc_size_t len,int flag,nsc_buf_t ** ptr)150*7836SJohn.Forte@Sun.COM nsc_alloc_buf(nsc_fd_t *fd, nsc_off_t pos, nsc_size_t len,
151*7836SJohn.Forte@Sun.COM     int flag, nsc_buf_t **ptr)
152*7836SJohn.Forte@Sun.COM {
153*7836SJohn.Forte@Sun.COM 	int (*fn)() = _nsc_alloc_buf_h;
154*7836SJohn.Forte@Sun.COM 
155*7836SJohn.Forte@Sun.COM 	if ((fd->sf_avail & NSC_WRITE) == 0)
156*7836SJohn.Forte@Sun.COM 		if (flag & NSC_WRBUF)
157*7836SJohn.Forte@Sun.COM 			return (EACCES);
158*7836SJohn.Forte@Sun.COM 
159*7836SJohn.Forte@Sun.COM 	if ((flag & (NSC_READ|NSC_WRITE|NSC_NODATA)) ==
160*7836SJohn.Forte@Sun.COM 	    (NSC_READ|NSC_NODATA)) {
161*7836SJohn.Forte@Sun.COM 		/*
162*7836SJohn.Forte@Sun.COM 		 * NSC_NODATA access checks.
163*7836SJohn.Forte@Sun.COM 		 *
164*7836SJohn.Forte@Sun.COM 		 * - NSC_READ|NSC_NODATA is illegal since there would
165*7836SJohn.Forte@Sun.COM 		 *   be no data buffer to immediately read the data into.
166*7836SJohn.Forte@Sun.COM 		 * - NSC_WRITE|NSC_NODATA is valid since the client can
167*7836SJohn.Forte@Sun.COM 		 *   provide the buffer and then call nsc_write() as
168*7836SJohn.Forte@Sun.COM 		 *   necessary.
169*7836SJohn.Forte@Sun.COM 		 * - NSC_NODATA is valid since the client can provide the
170*7836SJohn.Forte@Sun.COM 		 *   buffer and then call nsc_read() or nsc_write() as
171*7836SJohn.Forte@Sun.COM 		 *   necessary.
172*7836SJohn.Forte@Sun.COM 		 */
173*7836SJohn.Forte@Sun.COM 		return (EACCES);
174*7836SJohn.Forte@Sun.COM 	}
175*7836SJohn.Forte@Sun.COM 
176*7836SJohn.Forte@Sun.COM 	if (*ptr) {
177*7836SJohn.Forte@Sun.COM 		fn = fd->sf_aio->alloc_buf;
178*7836SJohn.Forte@Sun.COM 		(*ptr)->sb_fd = fd;
179*7836SJohn.Forte@Sun.COM 	}
180*7836SJohn.Forte@Sun.COM 
181*7836SJohn.Forte@Sun.COM 	return (*fn)(fd->sf_cd, pos, len, flag, ptr, fd);
182*7836SJohn.Forte@Sun.COM }
183*7836SJohn.Forte@Sun.COM 
184*7836SJohn.Forte@Sun.COM 
185*7836SJohn.Forte@Sun.COM /* ARGSUSED */
186*7836SJohn.Forte@Sun.COM 
187*7836SJohn.Forte@Sun.COM static int
_nsc_alloc_buf_h(blind_t cd,nsc_off_t pos,nsc_size_t len,int flag,nsc_buf_t ** ptr,nsc_fd_t * fd)188*7836SJohn.Forte@Sun.COM _nsc_alloc_buf_h(blind_t cd, nsc_off_t pos, nsc_size_t len,
189*7836SJohn.Forte@Sun.COM     int flag, nsc_buf_t **ptr, nsc_fd_t *fd)
190*7836SJohn.Forte@Sun.COM {
191*7836SJohn.Forte@Sun.COM 	nsc_buf_t *h;
192*7836SJohn.Forte@Sun.COM 	int rc;
193*7836SJohn.Forte@Sun.COM 
194*7836SJohn.Forte@Sun.COM 	if (!(h = nsc_alloc_handle(fd, NULL, NULL, NULL)))
195*7836SJohn.Forte@Sun.COM 		return (ENOBUFS);
196*7836SJohn.Forte@Sun.COM 
197*7836SJohn.Forte@Sun.COM 	if ((rc = nsc_alloc_buf(fd, pos, len, flag, &h)) <= 0) {
198*7836SJohn.Forte@Sun.COM 		h->sb_flag &= ~NSC_HALLOCATED;
199*7836SJohn.Forte@Sun.COM 		*ptr = h;
200*7836SJohn.Forte@Sun.COM 		return (rc);
201*7836SJohn.Forte@Sun.COM 	}
202*7836SJohn.Forte@Sun.COM 
203*7836SJohn.Forte@Sun.COM 	(void) nsc_free_handle(h);
204*7836SJohn.Forte@Sun.COM 	return (rc);
205*7836SJohn.Forte@Sun.COM }
206*7836SJohn.Forte@Sun.COM 
207*7836SJohn.Forte@Sun.COM 
208*7836SJohn.Forte@Sun.COM int
nsc_read(nsc_buf_t * h,nsc_off_t pos,nsc_size_t len,int flag)209*7836SJohn.Forte@Sun.COM nsc_read(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
210*7836SJohn.Forte@Sun.COM {
211*7836SJohn.Forte@Sun.COM 	if ((h->sb_flag & NSC_ABUF) ||
212*7836SJohn.Forte@Sun.COM 	    ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
213*7836SJohn.Forte@Sun.COM 		return (EIO);
214*7836SJohn.Forte@Sun.COM 
215*7836SJohn.Forte@Sun.COM 	return ((*h->sb_fd->sf_aio->read)(h, pos, len, flag));
216*7836SJohn.Forte@Sun.COM }
217*7836SJohn.Forte@Sun.COM 
218*7836SJohn.Forte@Sun.COM 
219*7836SJohn.Forte@Sun.COM int
nsc_write(nsc_buf_t * h,nsc_off_t pos,nsc_size_t len,int flag)220*7836SJohn.Forte@Sun.COM nsc_write(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
221*7836SJohn.Forte@Sun.COM {
222*7836SJohn.Forte@Sun.COM 	if ((h->sb_flag & NSC_ABUF) ||
223*7836SJohn.Forte@Sun.COM 	    ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
224*7836SJohn.Forte@Sun.COM 		return (EIO);
225*7836SJohn.Forte@Sun.COM 
226*7836SJohn.Forte@Sun.COM 	return ((*h->sb_fd->sf_aio->write)(h, pos, len, flag));
227*7836SJohn.Forte@Sun.COM }
228*7836SJohn.Forte@Sun.COM 
229*7836SJohn.Forte@Sun.COM 
230*7836SJohn.Forte@Sun.COM int
nsc_zero(nsc_buf_t * h,nsc_off_t pos,nsc_size_t len,int flag)231*7836SJohn.Forte@Sun.COM nsc_zero(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
232*7836SJohn.Forte@Sun.COM {
233*7836SJohn.Forte@Sun.COM 	if ((h->sb_flag & NSC_ABUF) ||
234*7836SJohn.Forte@Sun.COM 	    ((h->sb_flag & NSC_NODATA) && h->sb_vec == NULL))
235*7836SJohn.Forte@Sun.COM 		return (EIO);
236*7836SJohn.Forte@Sun.COM 
237*7836SJohn.Forte@Sun.COM 	return ((*h->sb_fd->sf_aio->zero)(h, pos, len, flag));
238*7836SJohn.Forte@Sun.COM }
239*7836SJohn.Forte@Sun.COM 
240*7836SJohn.Forte@Sun.COM 
241*7836SJohn.Forte@Sun.COM int
nsc_copy(nsc_buf_t * h1,nsc_buf_t * h2,nsc_off_t pos1,nsc_off_t pos2,nsc_size_t len)242*7836SJohn.Forte@Sun.COM nsc_copy(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
243*7836SJohn.Forte@Sun.COM     nsc_off_t pos2, nsc_size_t len)
244*7836SJohn.Forte@Sun.COM {
245*7836SJohn.Forte@Sun.COM 	nsc_io_t *io1, *io2;
246*7836SJohn.Forte@Sun.COM 	int rc = EIO;
247*7836SJohn.Forte@Sun.COM 
248*7836SJohn.Forte@Sun.COM 	if (((h1->sb_flag & NSC_NODATA) && h1->sb_vec == NULL) ||
249*7836SJohn.Forte@Sun.COM 	    ((h2->sb_flag & NSC_NODATA) && h2->sb_vec == NULL))
250*7836SJohn.Forte@Sun.COM 		return (EIO);
251*7836SJohn.Forte@Sun.COM 
252*7836SJohn.Forte@Sun.COM 	if (h1->sb_fd && h2->sb_fd) {
253*7836SJohn.Forte@Sun.COM 		io1 = (h1->sb_flag & NSC_ABUF) ?
254*7836SJohn.Forte@Sun.COM 		    (nsc_io_t *)h1->sb_fd : h1->sb_fd->sf_aio;
255*7836SJohn.Forte@Sun.COM 
256*7836SJohn.Forte@Sun.COM 		io2 = (h2->sb_flag & NSC_ABUF) ?
257*7836SJohn.Forte@Sun.COM 		    (nsc_io_t *)h2->sb_fd : h2->sb_fd->sf_aio;
258*7836SJohn.Forte@Sun.COM 
259*7836SJohn.Forte@Sun.COM 		if (io1 == io2)
260*7836SJohn.Forte@Sun.COM 			rc = (*io1->copy)(h1, h2, pos1, pos2, len);
261*7836SJohn.Forte@Sun.COM 	}
262*7836SJohn.Forte@Sun.COM 
263*7836SJohn.Forte@Sun.COM 	if (rc != EIO)
264*7836SJohn.Forte@Sun.COM 		return (rc);
265*7836SJohn.Forte@Sun.COM 
266*7836SJohn.Forte@Sun.COM 	return (_nsc_copy_h(h1, h2, pos1, pos2, len));
267*7836SJohn.Forte@Sun.COM }
268*7836SJohn.Forte@Sun.COM 
269*7836SJohn.Forte@Sun.COM 
270*7836SJohn.Forte@Sun.COM static int
_nsc_copy_h(nsc_buf_t * h1,nsc_buf_t * h2,nsc_off_t pos1,nsc_off_t pos2,nsc_size_t len)271*7836SJohn.Forte@Sun.COM _nsc_copy_h(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
272*7836SJohn.Forte@Sun.COM     nsc_off_t pos2, nsc_size_t len)
273*7836SJohn.Forte@Sun.COM {
274*7836SJohn.Forte@Sun.COM 	nsc_vec_t *v1, *v2;
275*7836SJohn.Forte@Sun.COM 	uchar_t *a1, *a2;
276*7836SJohn.Forte@Sun.COM 	int sz, l1, l2, lenbytes;	/* byte sizes within an nsc_vec_t */
277*7836SJohn.Forte@Sun.COM 
278*7836SJohn.Forte@Sun.COM 	if (pos1 < h1->sb_pos || pos1 + len > h1->sb_pos + h1->sb_len ||
279*7836SJohn.Forte@Sun.COM 	    pos2 < h2->sb_pos || pos2 + len > h2->sb_pos + h2->sb_len)
280*7836SJohn.Forte@Sun.COM 		return (EINVAL);
281*7836SJohn.Forte@Sun.COM 
282*7836SJohn.Forte@Sun.COM 	if (!len)
283*7836SJohn.Forte@Sun.COM 		return (0);
284*7836SJohn.Forte@Sun.COM 
285*7836SJohn.Forte@Sun.COM 	/* find starting point in "from" vector */
286*7836SJohn.Forte@Sun.COM 
287*7836SJohn.Forte@Sun.COM 	v1 = h1->sb_vec;
288*7836SJohn.Forte@Sun.COM 	pos1 -= h1->sb_pos;
289*7836SJohn.Forte@Sun.COM 
290*7836SJohn.Forte@Sun.COM 	for (; pos1 >= FBA_NUM(v1->sv_len); v1++)
291*7836SJohn.Forte@Sun.COM 		pos1 -= FBA_NUM(v1->sv_len);
292*7836SJohn.Forte@Sun.COM 
293*7836SJohn.Forte@Sun.COM 	a1 = v1->sv_addr + FBA_SIZE(pos1);
294*7836SJohn.Forte@Sun.COM 	l1 = v1->sv_len - FBA_SIZE(pos1);
295*7836SJohn.Forte@Sun.COM 
296*7836SJohn.Forte@Sun.COM 	/* find starting point in "to" vector */
297*7836SJohn.Forte@Sun.COM 
298*7836SJohn.Forte@Sun.COM 	v2 = h2->sb_vec;
299*7836SJohn.Forte@Sun.COM 	pos2 -= h2->sb_pos;
300*7836SJohn.Forte@Sun.COM 
301*7836SJohn.Forte@Sun.COM 	for (; pos2 >= FBA_NUM(v2->sv_len); v2++)
302*7836SJohn.Forte@Sun.COM 		pos2 -= FBA_NUM(v2->sv_len);
303*7836SJohn.Forte@Sun.COM 
304*7836SJohn.Forte@Sun.COM 	a2 = v2->sv_addr + FBA_SIZE(pos2);
305*7836SJohn.Forte@Sun.COM 	l2 = v2->sv_len - FBA_SIZE(pos2);
306*7836SJohn.Forte@Sun.COM 
307*7836SJohn.Forte@Sun.COM 	/* copy required data */
308*7836SJohn.Forte@Sun.COM 
309*7836SJohn.Forte@Sun.COM 	ASSERT(FBA_SIZE(len) < INT_MAX);
310*7836SJohn.Forte@Sun.COM 	lenbytes = (int)FBA_SIZE(len);
311*7836SJohn.Forte@Sun.COM 
312*7836SJohn.Forte@Sun.COM 	while (lenbytes) {
313*7836SJohn.Forte@Sun.COM 		sz = min(l1, l2);
314*7836SJohn.Forte@Sun.COM 		sz = min(sz, lenbytes);
315*7836SJohn.Forte@Sun.COM 
316*7836SJohn.Forte@Sun.COM 		bcopy(a1, a2, sz);
317*7836SJohn.Forte@Sun.COM 
318*7836SJohn.Forte@Sun.COM 		l1 -= sz; l2 -= sz;
319*7836SJohn.Forte@Sun.COM 		a1 += sz; a2 += sz;
320*7836SJohn.Forte@Sun.COM 		lenbytes -= sz;
321*7836SJohn.Forte@Sun.COM 
322*7836SJohn.Forte@Sun.COM 		if (!l1)
323*7836SJohn.Forte@Sun.COM 			a1 = (++v1)->sv_addr, l1 = v1->sv_len;
324*7836SJohn.Forte@Sun.COM 		if (!l2)
325*7836SJohn.Forte@Sun.COM 			a2 = (++v2)->sv_addr, l2 = v2->sv_len;
326*7836SJohn.Forte@Sun.COM 	}
327*7836SJohn.Forte@Sun.COM 
328*7836SJohn.Forte@Sun.COM 	return (0);
329*7836SJohn.Forte@Sun.COM }
330*7836SJohn.Forte@Sun.COM 
331*7836SJohn.Forte@Sun.COM 
332*7836SJohn.Forte@Sun.COM int
nsc_copy_direct(nsc_buf_t * h1,nsc_buf_t * h2,nsc_off_t pos1,nsc_off_t pos2,nsc_size_t len)333*7836SJohn.Forte@Sun.COM nsc_copy_direct(nsc_buf_t *h1, nsc_buf_t *h2, nsc_off_t pos1,
334*7836SJohn.Forte@Sun.COM     nsc_off_t pos2, nsc_size_t len)
335*7836SJohn.Forte@Sun.COM {
336*7836SJohn.Forte@Sun.COM 	int rc = EIO;
337*7836SJohn.Forte@Sun.COM 
338*7836SJohn.Forte@Sun.COM 	if (!h1 || !h2)
339*7836SJohn.Forte@Sun.COM 		return (EINVAL);
340*7836SJohn.Forte@Sun.COM 
341*7836SJohn.Forte@Sun.COM 	if (((h1->sb_flag & NSC_NODATA) && h1->sb_vec == NULL) ||
342*7836SJohn.Forte@Sun.COM 	    ((h2->sb_flag & NSC_NODATA) && h2->sb_vec == NULL))
343*7836SJohn.Forte@Sun.COM 		return (EIO);
344*7836SJohn.Forte@Sun.COM 
345*7836SJohn.Forte@Sun.COM 	if ((h2->sb_flag & NSC_RDWR) != NSC_WRITE) {
346*7836SJohn.Forte@Sun.COM 		cmn_err(CE_WARN,
347*7836SJohn.Forte@Sun.COM 		    "nsc_copy_direct: h2 (%p) flags (%x) include NSC_READ",
348*7836SJohn.Forte@Sun.COM 		    (void *)h2, h2->sb_flag);
349*7836SJohn.Forte@Sun.COM 	}
350*7836SJohn.Forte@Sun.COM 
351*7836SJohn.Forte@Sun.COM 	if ((h2->sb_flag & NSC_WRTHRU) == 0) {
352*7836SJohn.Forte@Sun.COM 		cmn_err(CE_WARN,
353*7836SJohn.Forte@Sun.COM 		    "nsc_copy_direct: h2 (%p) flags (%x) do not "
354*7836SJohn.Forte@Sun.COM 		    "include NSC_WRTHRU", (void *)h2, h2->sb_flag);
355*7836SJohn.Forte@Sun.COM 		h2->sb_flag |= NSC_WRTHRU;
356*7836SJohn.Forte@Sun.COM 	}
357*7836SJohn.Forte@Sun.COM 
358*7836SJohn.Forte@Sun.COM 	if (h1->sb_fd && h2->sb_fd && h1->sb_fd->sf_aio == h2->sb_fd->sf_aio)
359*7836SJohn.Forte@Sun.COM 		rc = (*h1->sb_fd->sf_aio->copy_direct)(h1, h2, pos1, pos2, len);
360*7836SJohn.Forte@Sun.COM 
361*7836SJohn.Forte@Sun.COM 	if (rc != EIO)
362*7836SJohn.Forte@Sun.COM 		return (rc);
363*7836SJohn.Forte@Sun.COM 
364*7836SJohn.Forte@Sun.COM 	/*
365*7836SJohn.Forte@Sun.COM 	 * The slow way ...
366*7836SJohn.Forte@Sun.COM 	 */
367*7836SJohn.Forte@Sun.COM 
368*7836SJohn.Forte@Sun.COM 	rc = nsc_copy(h1, h2, pos1, pos2, len);
369*7836SJohn.Forte@Sun.COM 	if (rc <= 0)
370*7836SJohn.Forte@Sun.COM 		rc = nsc_write(h2, pos2, len, NSC_WRTHRU);
371*7836SJohn.Forte@Sun.COM 
372*7836SJohn.Forte@Sun.COM 	return (rc);
373*7836SJohn.Forte@Sun.COM }
374*7836SJohn.Forte@Sun.COM 
375*7836SJohn.Forte@Sun.COM 
376*7836SJohn.Forte@Sun.COM int
nsc_uncommit(nsc_buf_t * h,nsc_off_t pos,nsc_size_t len,int flag)377*7836SJohn.Forte@Sun.COM nsc_uncommit(nsc_buf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
378*7836SJohn.Forte@Sun.COM {
379*7836SJohn.Forte@Sun.COM 	if (h->sb_flag & NSC_ABUF)
380*7836SJohn.Forte@Sun.COM 		return (EIO);
381*7836SJohn.Forte@Sun.COM 
382*7836SJohn.Forte@Sun.COM 	return ((*h->sb_fd->sf_aio->uncommit)(h, pos, len, flag));
383*7836SJohn.Forte@Sun.COM }
384*7836SJohn.Forte@Sun.COM 
385*7836SJohn.Forte@Sun.COM 
386*7836SJohn.Forte@Sun.COM int
nsc_free_buf(nsc_buf_t * h)387*7836SJohn.Forte@Sun.COM nsc_free_buf(nsc_buf_t *h)
388*7836SJohn.Forte@Sun.COM {
389*7836SJohn.Forte@Sun.COM 	nsc_io_t *io;
390*7836SJohn.Forte@Sun.COM 	int abuf;
391*7836SJohn.Forte@Sun.COM 	int rc;
392*7836SJohn.Forte@Sun.COM 
393*7836SJohn.Forte@Sun.COM 	if (h == NULL)
394*7836SJohn.Forte@Sun.COM 		return (0);
395*7836SJohn.Forte@Sun.COM 
396*7836SJohn.Forte@Sun.COM 	if ((h->sb_flag & NSC_NODATA) && (h->sb_vec != NULL)) {
397*7836SJohn.Forte@Sun.COM 		h->sb_vec = NULL;
398*7836SJohn.Forte@Sun.COM 	}
399*7836SJohn.Forte@Sun.COM 
400*7836SJohn.Forte@Sun.COM 	abuf = (h->sb_flag & NSC_ABUF);
401*7836SJohn.Forte@Sun.COM 
402*7836SJohn.Forte@Sun.COM 	if (abuf)
403*7836SJohn.Forte@Sun.COM 		io = (nsc_io_t *)h->sb_fd;
404*7836SJohn.Forte@Sun.COM 	else
405*7836SJohn.Forte@Sun.COM 		io = h->sb_fd->sf_aio;
406*7836SJohn.Forte@Sun.COM 
407*7836SJohn.Forte@Sun.COM 	rc = (*io->free_buf)(h);
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM 	if (abuf && rc <= 0) {
410*7836SJohn.Forte@Sun.COM 		mutex_enter(&_nsc_io_lock);
411*7836SJohn.Forte@Sun.COM 		io->abufcnt--;
412*7836SJohn.Forte@Sun.COM 		mutex_exit(&_nsc_io_lock);
413*7836SJohn.Forte@Sun.COM 	}
414*7836SJohn.Forte@Sun.COM 
415*7836SJohn.Forte@Sun.COM 	return (rc);
416*7836SJohn.Forte@Sun.COM }
417*7836SJohn.Forte@Sun.COM 
418*7836SJohn.Forte@Sun.COM 
419*7836SJohn.Forte@Sun.COM int
nsc_node_hints(uint_t * hints)420*7836SJohn.Forte@Sun.COM nsc_node_hints(uint_t *hints)
421*7836SJohn.Forte@Sun.COM {
422*7836SJohn.Forte@Sun.COM 	return (_nsc_call_io(_I(nodehints), (blind_t)hints,
423*7836SJohn.Forte@Sun.COM 	    (blind_t)NSC_GET_NODE_HINT, 0));
424*7836SJohn.Forte@Sun.COM }
425*7836SJohn.Forte@Sun.COM 
426*7836SJohn.Forte@Sun.COM int
nsc_node_hints_set(uint_t hints)427*7836SJohn.Forte@Sun.COM nsc_node_hints_set(uint_t hints)
428*7836SJohn.Forte@Sun.COM {
429*7836SJohn.Forte@Sun.COM 	return (_nsc_call_io(_I(nodehints), (blind_t)(unsigned long)hints,
430*7836SJohn.Forte@Sun.COM 	    (blind_t)NSC_SET_NODE_HINT, 0));
431*7836SJohn.Forte@Sun.COM }
432*7836SJohn.Forte@Sun.COM 
433*7836SJohn.Forte@Sun.COM 
434*7836SJohn.Forte@Sun.COM int
nsc_cache_sizes(int * asize,int * wsize)435*7836SJohn.Forte@Sun.COM nsc_cache_sizes(int *asize, int *wsize)
436*7836SJohn.Forte@Sun.COM {
437*7836SJohn.Forte@Sun.COM 	return (_nsc_call_io(_I(sizes), (blind_t)asize, (blind_t)wsize, 0));
438*7836SJohn.Forte@Sun.COM }
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 
441*7836SJohn.Forte@Sun.COM int
nsc_set_trksize(nsc_fd_t * fd,nsc_size_t trsize)442*7836SJohn.Forte@Sun.COM nsc_set_trksize(nsc_fd_t *fd, nsc_size_t trsize)
443*7836SJohn.Forte@Sun.COM {
444*7836SJohn.Forte@Sun.COM 	return (*fd->sf_aio->trksize)(fd->sf_cd, trsize);
445*7836SJohn.Forte@Sun.COM }
446*7836SJohn.Forte@Sun.COM 
447*7836SJohn.Forte@Sun.COM 
448*7836SJohn.Forte@Sun.COM int
nsc_get_pinned(nsc_fd_t * fd)449*7836SJohn.Forte@Sun.COM nsc_get_pinned(nsc_fd_t *fd)
450*7836SJohn.Forte@Sun.COM {
451*7836SJohn.Forte@Sun.COM 	return (*fd->sf_aio->getpin)(fd->sf_cd);
452*7836SJohn.Forte@Sun.COM }
453*7836SJohn.Forte@Sun.COM 
454*7836SJohn.Forte@Sun.COM 
455*7836SJohn.Forte@Sun.COM int
nsc_discard_pinned(nsc_fd_t * fd,nsc_off_t pos,nsc_size_t len)456*7836SJohn.Forte@Sun.COM nsc_discard_pinned(nsc_fd_t *fd, nsc_off_t pos, nsc_size_t len)
457*7836SJohn.Forte@Sun.COM {
458*7836SJohn.Forte@Sun.COM 	return (*fd->sf_aio->discard)(fd->sf_cd, pos, len);
459*7836SJohn.Forte@Sun.COM }
460*7836SJohn.Forte@Sun.COM 
461*7836SJohn.Forte@Sun.COM 
462*7836SJohn.Forte@Sun.COM void
nsc_pinned_data(nsc_iodev_t * iodev,nsc_off_t pos,nsc_size_t len)463*7836SJohn.Forte@Sun.COM nsc_pinned_data(nsc_iodev_t *iodev, nsc_off_t pos, nsc_size_t len)
464*7836SJohn.Forte@Sun.COM {
465*7836SJohn.Forte@Sun.COM 	nsc_fd_t *fd;
466*7836SJohn.Forte@Sun.COM 
467*7836SJohn.Forte@Sun.COM 	if (!iodev)
468*7836SJohn.Forte@Sun.COM 		return;
469*7836SJohn.Forte@Sun.COM 
470*7836SJohn.Forte@Sun.COM 	mutex_enter(&iodev->si_dev->nsc_lock);
471*7836SJohn.Forte@Sun.COM 	iodev->si_busy++;
472*7836SJohn.Forte@Sun.COM 	mutex_exit(&iodev->si_dev->nsc_lock);
473*7836SJohn.Forte@Sun.COM 
474*7836SJohn.Forte@Sun.COM 	for (fd = iodev->si_open; fd; fd = fd->sf_next)
475*7836SJohn.Forte@Sun.COM 		if (fd->sf_avail & _NSC_ATTACH)
476*7836SJohn.Forte@Sun.COM 			(*fd->sf_pinned)(fd->sf_arg, pos, len);
477*7836SJohn.Forte@Sun.COM 
478*7836SJohn.Forte@Sun.COM 	_nsc_wake_dev(iodev->si_dev, &iodev->si_busy);
479*7836SJohn.Forte@Sun.COM }
480*7836SJohn.Forte@Sun.COM 
481*7836SJohn.Forte@Sun.COM 
482*7836SJohn.Forte@Sun.COM void
nsc_unpinned_data(nsc_iodev_t * iodev,nsc_off_t pos,nsc_size_t len)483*7836SJohn.Forte@Sun.COM nsc_unpinned_data(nsc_iodev_t *iodev, nsc_off_t pos, nsc_size_t len)
484*7836SJohn.Forte@Sun.COM {
485*7836SJohn.Forte@Sun.COM 	nsc_fd_t *fd;
486*7836SJohn.Forte@Sun.COM 
487*7836SJohn.Forte@Sun.COM 	if (!iodev)
488*7836SJohn.Forte@Sun.COM 		return;
489*7836SJohn.Forte@Sun.COM 
490*7836SJohn.Forte@Sun.COM 	mutex_enter(&iodev->si_dev->nsc_lock);
491*7836SJohn.Forte@Sun.COM 	iodev->si_busy++;
492*7836SJohn.Forte@Sun.COM 	mutex_exit(&iodev->si_dev->nsc_lock);
493*7836SJohn.Forte@Sun.COM 
494*7836SJohn.Forte@Sun.COM 	for (fd = iodev->si_open; fd; fd = fd->sf_next)
495*7836SJohn.Forte@Sun.COM 		if (fd->sf_avail & _NSC_ATTACH)
496*7836SJohn.Forte@Sun.COM 			(*fd->sf_unpinned)(fd->sf_arg, pos, len);
497*7836SJohn.Forte@Sun.COM 
498*7836SJohn.Forte@Sun.COM 	_nsc_wake_dev(iodev->si_dev, &iodev->si_busy);
499*7836SJohn.Forte@Sun.COM }
500