Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/avs/ns/nsctl/nsc_disk.c
+++ new/usr/src/uts/common/avs/ns/nsctl/nsc_disk.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <sys/types.h>
27 27 #include <sys/ksynch.h>
28 28 #include <sys/errno.h>
29 29 #include <sys/file.h>
30 30 #include <sys/open.h>
31 31 #include <sys/cred.h>
32 32 #include <sys/kmem.h>
33 33 #include <sys/uio.h>
34 34 #include <sys/ddi.h>
35 35 #include <sys/sdt.h>
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
36 36
37 37 #define __NSC_GEN__
38 38 #include "nsc_dev.h"
39 39 #include "nsc_disk.h"
40 40 #include "../nsctl.h"
41 41
42 42
43 43 #define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long))
44 44
45 45 nsc_def_t _nsc_disk_def[] = {
46 - "UserRead", (uintptr_t)nsc_ioerr, _I(uread),
47 - "UserWrite", (uintptr_t)nsc_ioerr, _I(uwrite),
48 - "PartSize", (uintptr_t)nsc_null, _I(partsize),
49 - "MaxFbas", (uintptr_t)nsc_null, _I(maxfbas),
50 - "Control", (uintptr_t)nsc_ioerr, _I(control),
51 - 0, 0, 0
46 + { "UserRead", (uintptr_t)nsc_ioerr, _I(uread) },
47 + { "UserWrite", (uintptr_t)nsc_ioerr, _I(uwrite) },
48 + { "PartSize", (uintptr_t)nsc_null, _I(partsize) },
49 + { "MaxFbas", (uintptr_t)nsc_null, _I(maxfbas) },
50 + { "Control", (uintptr_t)nsc_ioerr, _I(control) },
51 + { NULL, (uintptr_t)NULL, 0 }
52 52 };
53 53
54 54
55 55 extern nsc_mem_t *_nsc_local_mem;
56 56
57 57 static int _nsc_uread(dev_t, uio_t *, cred_t *, nsc_fd_t *);
58 58 static int _nsc_uwrite(dev_t, uio_t *, cred_t *, nsc_fd_t *);
59 59 static int _nsc_rw_uio(nsc_fd_t *, uio_t *, uio_rw_t);
60 60
61 61 static int _nsc_free_dhandle(nsc_dbuf_t *);
62 62 static int _nsc_alloc_dbuf(blind_t, nsc_off_t, nsc_size_t, int, nsc_dbuf_t **);
63 63 static int _nsc_free_dbuf(nsc_dbuf_t *);
64 64 static void _nsc_wait_dbuf(nsc_dbuf_t *);
65 65 static int _nsc_read_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
66 66 static int _nsc_write_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
67 67 static int _nsc_zero_dbuf(nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
68 68 static int _nsc_dbuf_io(int (*)(), nsc_dbuf_t *, nsc_off_t, nsc_size_t, int);
69 69
70 70 static nsc_dbuf_t *_nsc_alloc_dhandle(void (*)(), void (*)(), void (*)());
71 71
72 72
73 73 /*
74 74 * void
75 75 * _nsc_add_disk (nsc_io_t *io)
76 76 * Add disk interface functions.
77 77 *
78 78 * Calling/Exit State:
79 79 * Updates the I/O module with the appropriate
80 80 * interface routines.
81 81 *
82 82 * Description:
83 83 * Add functions to the I/O module to provide a disk
84 84 * or cache interface as appropriate.
85 85 */
86 86 void
87 87 _nsc_add_disk(nsc_io_t *io)
88 88 {
89 89 if ((io->alloc_buf != nsc_ioerr && io->free_buf != nsc_fatal) ||
90 90 (io->flag & NSC_FILTER)) {
91 91 if (io->uread == nsc_ioerr)
92 92 io->uread = _nsc_uread;
93 93
94 94 if (io->uwrite == nsc_ioerr &&
95 95 (io->write != nsc_fatal || (io->flag & NSC_FILTER)))
96 96 io->uwrite = _nsc_uwrite;
97 97
98 98 return;
99 99 }
100 100
101 101 if (io->alloc_h != (nsc_buf_t *(*)())nsc_null ||
102 102 io->free_h != nsc_fatal || io->alloc_buf != nsc_ioerr ||
103 103 io->free_buf != nsc_fatal || io->read != nsc_fatal ||
104 104 io->write != nsc_fatal || io->zero != nsc_fatal)
105 105 return;
106 106
107 107 if (io->uread == nsc_ioerr && io->uwrite == nsc_ioerr)
108 108 return;
109 109
110 110 /*
111 111 * Layer the generic nsc_buf_t provider onto a uio_t provider.
112 112 */
113 113
114 114 io->alloc_h = (nsc_buf_t *(*)())_nsc_alloc_dhandle;
115 115 io->free_h = _nsc_free_dhandle;
116 116 io->alloc_buf = _nsc_alloc_dbuf;
117 117 io->free_buf = _nsc_free_dbuf;
118 118
119 119 io->read = _nsc_read_dbuf;
120 120 io->write = _nsc_write_dbuf;
121 121 io->zero = _nsc_zero_dbuf;
122 122
123 123 io->provide |= NSC_ANON;
124 124 }
125 125
126 126
127 127 int
128 128 nsc_uread(nsc_fd_t *fd, void *uiop, void *crp)
129 129 {
130 130 return (*fd->sf_aio->uread)(fd->sf_cd, uiop, crp, fd);
131 131 }
132 132
133 133
134 134 int
135 135 nsc_uwrite(nsc_fd_t *fd, void *uiop, void *crp)
136 136 {
137 137 if ((fd->sf_avail & NSC_WRITE) == 0)
138 138 return (EIO);
139 139
140 140 return (*fd->sf_aio->uwrite)(fd->sf_cd, uiop, crp, fd);
141 141 }
142 142
143 143
144 144 int
145 145 nsc_partsize(nsc_fd_t *fd, nsc_size_t *valp)
146 146 {
147 147 *valp = 0;
148 148 return (*fd->sf_aio->partsize)(fd->sf_cd, valp);
149 149 }
150 150
151 151
152 152 int
153 153 nsc_maxfbas(nsc_fd_t *fd, int flag, nsc_size_t *valp)
154 154 {
155 155 *valp = 0;
156 156 return (*fd->sf_aio->maxfbas)(fd->sf_cd, flag, valp);
157 157 }
158 158
159 159 int
160 160 nsc_control(nsc_fd_t *fd, int command, void *argp, int argl)
161 161 {
162 162 return (*fd->sf_aio->control)(fd->sf_cd, command, argp, argl);
163 163 }
164 164
165 165
166 166 /* ARGSUSED */
167 167
168 168 static int
169 169 _nsc_uread(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
170 170 {
171 171 return (_nsc_rw_uio(fd, uiop, UIO_READ));
172 172 }
173 173
174 174
175 175 /* ARGSUSED */
176 176
177 177 static int
178 178 _nsc_uwrite(dev_t dev, uio_t *uiop, cred_t *crp, nsc_fd_t *fd)
179 179 {
180 180 return (_nsc_rw_uio(fd, uiop, UIO_WRITE));
181 181 }
182 182
183 183
184 184 static int
185 185 _nsc_rw_uio(nsc_fd_t *fd, uio_t *uiop, uio_rw_t rw)
186 186 {
187 187 nsc_size_t buflen, len, limit, chunk;
188 188 nsc_off_t pos, off;
189 189 nsc_buf_t *buf;
190 190 nsc_vec_t *vec;
191 191 size_t n;
192 192 int rc;
193 193
194 194 pos = FPOS_TO_FBA(uiop);
195 195 off = FPOS_TO_OFF(uiop);
196 196 len = FBA_LEN(uiop->uio_resid + off);
197 197
198 198 DTRACE_PROBE3(_nsc_rw_uio_io,
199 199 uint64_t, pos,
200 200 uint64_t, off,
201 201 uint64_t, len);
202 202
203 203 /* prevent non-FBA bounded I/O - this is a disk driver! */
204 204 if (off != 0 || FBA_OFF(uiop->uio_resid) != 0)
205 205 return (EINVAL);
206 206
207 207 if ((rc = nsc_partsize(fd, &limit)) != 0)
208 208 return (rc);
209 209
210 210 if ((rc = nsc_maxfbas(fd, 0, &chunk)) != 0)
211 211 return (rc);
212 212
213 213 DTRACE_PROBE2(_nsc_rw_uio_limit,
214 214 uint64_t, limit,
215 215 uint64_t, chunk);
216 216
217 217 if (limit && pos >= limit) {
218 218 if (pos > limit || rw == UIO_WRITE)
219 219 return (ENXIO);
220 220 return (0);
221 221 }
222 222
223 223 if (limit && pos + len > limit)
224 224 len = limit - pos;
225 225
226 226 while (len > 0) {
227 227 buflen = min(len, chunk);
228 228
229 229 buf = NULL; /* always use a temporary buffer */
230 230 if ((rc = nsc_alloc_buf(fd, pos, buflen,
231 231 (rw == UIO_READ) ? NSC_RDBUF : NSC_WRBUF, &buf)) > 0)
232 232 return (rc);
233 233
234 234 vec = buf->sb_vec;
235 235
236 236 for (rc = 0;
237 237 !rc && uiop->uio_resid && vec->sv_addr;
238 238 vec++, off = 0) {
239 239 n = min(vec->sv_len - off, uiop->uio_resid);
240 240 rc = uiomove((char *)vec->sv_addr + off,
241 241 n, rw, uiop);
242 242 }
243 243
244 244 if (rw == UIO_WRITE) {
245 245 if (rc) {
246 246 (void) nsc_uncommit(buf, pos, buflen, 0);
247 247 } else if ((rc = nsc_write(buf, pos, buflen, 0)) < 0) {
248 248 rc = 0;
249 249 }
250 250 }
251 251
252 252 (void) nsc_free_buf(buf);
253 253
254 254 len -= buflen;
255 255 pos += buflen;
256 256 }
257 257
258 258 return (rc);
259 259 }
260 260
261 261
262 262 /* ARGSUSED */
263 263
264 264 static nsc_dbuf_t *
265 265 _nsc_alloc_dhandle(void (*d_cb)(), void (*r_cb)(), void (*w_cb)())
266 266 {
267 267 nsc_dbuf_t *h;
268 268
269 269 if ((h = nsc_kmem_zalloc(sizeof (nsc_dbuf_t),
270 270 KM_SLEEP, _nsc_local_mem)) == NULL)
271 271 return (NULL);
272 272
273 273 h->db_disc = d_cb;
274 274 h->db_flag = NSC_HALLOCATED;
275 275
276 276 return (h);
277 277 }
278 278
279 279
280 280 static int
281 281 _nsc_free_dhandle(nsc_dbuf_t *h)
282 282 {
283 283 nsc_kmem_free(h, sizeof (*h));
284 284 return (0);
285 285 }
286 286
287 287
288 288 static int
289 289 _nsc_alloc_dbuf(blind_t cd, nsc_off_t pos, nsc_size_t len,
290 290 int flag, nsc_dbuf_t **hp)
291 291 {
292 292 nsc_dbuf_t *h = *hp;
293 293 int rc;
294 294
295 295 if (cd == NSC_ANON_CD) {
296 296 flag &= ~(NSC_READ | NSC_WRITE | NSC_RDAHEAD);
297 297 } else {
298 298 if (h->db_maxfbas == 0) {
299 299 rc = nsc_maxfbas(h->db_fd, 0, &h->db_maxfbas);
300 300 if (rc != 0)
301 301 return (rc);
302 302 else if (h->db_maxfbas == 0)
303 303 return (EIO);
304 304 }
305 305
306 306 if (len > h->db_maxfbas)
307 307 return (ENOSPC);
308 308 }
309 309
310 310 if (flag & NSC_NODATA) {
311 311 ASSERT(!(flag & NSC_RDBUF));
312 312 h->db_addr = NULL;
313 313 } else {
314 314 if (h->db_disc)
315 315 (*h->db_disc)(h);
316 316
317 317 if (!(h->db_addr = nsc_kmem_alloc(FBA_SIZE(len), KM_SLEEP, 0)))
318 318 return (ENOMEM);
319 319 }
320 320
321 321 h->db_pos = pos;
322 322 h->db_len = len;
323 323 h->db_error = 0;
324 324 h->db_flag |= flag;
325 325
326 326 if (flag & NSC_NODATA) {
327 327 h->db_vec = NULL;
328 328 } else {
329 329 h->db_vec = &h->db_bvec[0];
330 330 h->db_bvec[0].sv_len = FBA_SIZE(len);
331 331 h->db_bvec[0].sv_addr = (void *)h->db_addr;
332 332 h->db_bvec[0].sv_vme = 0;
333 333
334 334 h->db_bvec[1].sv_len = 0;
335 335 h->db_bvec[1].sv_addr = 0;
336 336 h->db_bvec[1].sv_vme = 0;
337 337 }
338 338
339 339 if ((flag & NSC_RDAHEAD) || (cd == NSC_ANON_CD))
340 340 return (NSC_DONE);
341 341
342 342 _nsc_wait_dbuf(h);
343 343
344 344 if (flag & NSC_RDBUF) {
345 345 if ((rc = _nsc_dbuf_io(nsc_uread, h, pos, len, flag)) != 0) {
346 346 (void) _nsc_free_dbuf(h);
347 347 return (rc);
348 348 }
349 349 }
350 350
351 351 return (NSC_DONE);
352 352 }
353 353
354 354
355 355 static void
356 356 _nsc_wait_dbuf(nsc_dbuf_t *h)
357 357 {
358 358 nsc_iodev_t *iodev = h->db_fd->sf_iodev;
359 359 void (*fn)() = h->db_disc;
360 360 nsc_dbuf_t *hp;
361 361
362 362 mutex_enter(&iodev->si_lock);
363 363
364 364 h->db_next = iodev->si_active;
365 365 iodev->si_active = h;
366 366
367 367 /* CONSTCOND */
368 368
369 369 while (1) {
370 370 for (hp = h->db_next; hp; hp = hp->db_next)
371 371 if (h->db_pos + h->db_len > hp->db_pos &&
372 372 h->db_pos < hp->db_pos + hp->db_len) break;
373 373
374 374 if (!hp)
375 375 break;
376 376
377 377 if (fn)
378 378 (*fn)(h), fn = NULL;
379 379
380 380 cv_wait(&iodev->si_cv, &iodev->si_lock);
381 381 }
382 382
383 383 mutex_exit(&iodev->si_lock);
384 384 }
385 385
386 386
387 387 static int
388 388 _nsc_free_dbuf(nsc_dbuf_t *h)
389 389 {
390 390 nsc_dbuf_t **hpp, *hp;
391 391 nsc_iodev_t *iodev;
392 392 int wake = 0;
393 393
394 394 if (h->db_fd && !(h->db_flag & NSC_ABUF)) {
395 395 iodev = h->db_fd->sf_iodev;
396 396
397 397 mutex_enter(&iodev->si_lock);
398 398
399 399 hpp = (nsc_dbuf_t **)&iodev->si_active;
400 400
401 401 for (; *hpp; hpp = &hp->db_next) {
402 402 if ((hp = *hpp) == h) {
403 403 *hpp = h->db_next;
404 404 break;
405 405 }
406 406
407 407 if (h->db_pos + h->db_len > hp->db_pos &&
408 408 h->db_pos < hp->db_pos + hp->db_len) wake = 1;
409 409
410 410 }
411 411 if (wake)
412 412 cv_broadcast(&iodev->si_cv);
413 413
414 414 mutex_exit(&iodev->si_lock);
415 415 }
416 416
417 417 if (!(h->db_flag & NSC_NODATA) && h->db_addr)
418 418 nsc_kmem_free(h->db_addr, FBA_SIZE(h->db_len));
419 419
420 420 h->db_addr = NULL;
421 421 h->db_flag &= NSC_HALLOCATED; /* clear flags, preserve NSC_HALLOCATED */
422 422
423 423 if ((h->db_flag & NSC_HALLOCATED) == 0)
424 424 (void) _nsc_free_dhandle(h);
425 425
426 426
427 427 return (0);
428 428 }
429 429
430 430
431 431 static int
432 432 _nsc_read_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
433 433 {
434 434 return (_nsc_dbuf_io(nsc_uread, h, pos, len, flag));
435 435 }
436 436
437 437
438 438 static int
439 439 _nsc_write_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
440 440 {
441 441 return (_nsc_dbuf_io(nsc_uwrite, h, pos, len, flag));
442 442 }
443 443
444 444
445 445 static int
446 446 _nsc_zero_dbuf(nsc_dbuf_t *h, nsc_off_t pos, nsc_size_t len, int flag)
447 447 {
448 448 return (_nsc_dbuf_io(NULL, h, pos, len, flag));
449 449 }
450 450
451 451
452 452 static int
453 453 _nsc_dbuf_io(int (*fn)(), nsc_dbuf_t *h, nsc_off_t pos,
454 454 nsc_size_t len, int flag)
455 455 {
456 456 nsc_vec_t *vp = NULL;
457 457 cred_t *crp = NULL;
458 458 iovec_t *iovp;
459 459 nsc_size_t thisio; /* bytes in this io */
460 460 nsc_size_t todo; /* anticipated bytes to go */
461 461 nsc_size_t truedo; /* actual bytes to go */
462 462 nsc_off_t xpos; /* offset of this io */
463 463 int destidx;
464 464 nsc_size_t firstentryfix; /* value used for first entry */
465 465
466 466 int (*iofn)();
467 467 int rc = 0;
468 468
469 469 if (!h->db_vec || (h->db_flag & NSC_ABUF))
470 470 return (EIO);
471 471
472 472 if (pos < h->db_pos || pos + len > h->db_pos + h->db_len)
473 473 return (EINVAL);
474 474
475 475 if (!len)
476 476 return (0);
477 477 if (fn == nsc_uread && (flag & NSC_RDAHEAD))
478 478 return (0);
479 479
480 480 if (h->db_disc)
481 481 (*h->db_disc)(h);
482 482
483 483 crp = ddi_get_cred();
484 484 bzero(&h->db_uio, sizeof (uio_t));
485 485 bzero(&h->db_iov[0], (_NSC_DBUF_NVEC * sizeof (iovec_t)));
486 486
487 487 todo = FBA_SIZE(len);
488 488
489 489 /*
490 490 * determine where in the vector array we should start.
491 491 */
492 492 vp = h->db_vec;
493 493 xpos = pos - h->db_pos;
494 494 for (; xpos >= FBA_NUM(vp->sv_len); vp++)
495 495 xpos -= FBA_NUM(vp->sv_len);
496 496
497 497 firstentryfix = FBA_SIZE(xpos);
498 498
499 499 xpos = pos;
500 500
501 501 /*
502 502 * Loop performing i/o to the underlying driver.
503 503 */
504 504 while (todo) {
505 505 destidx = 0;
506 506 thisio = 0;
507 507 iofn = fn;
508 508
509 509 /*
510 510 * Copy up to _NSC_DBUF_NVEC vector entries from the
511 511 * nsc_vec_t into the iovec_t so that the number of
512 512 * i/o operations is minimised.
513 513 */
514 514 while (destidx < _NSC_DBUF_NVEC && todo) {
515 515 iovp = &h->db_iov[destidx];
516 516
517 517 ASSERT(FBA_LEN(vp->sv_len) == FBA_NUM(vp->sv_len));
518 518 ASSERT((vp->sv_len - firstentryfix) && vp->sv_addr);
519 519
520 520 truedo = min(vp->sv_len - firstentryfix, todo);
521 521 iovp->iov_base = (caddr_t)vp->sv_addr + firstentryfix;
522 522 firstentryfix = 0;
523 523 iovp->iov_len = (size_t)truedo;
524 524 if (!iofn) {
525 525 bzero(iovp->iov_base, iovp->iov_len);
526 526 }
527 527 thisio += truedo;
528 528 todo -= truedo;
529 529 destidx++;
530 530 vp++;
531 531 }
532 532
533 533 h->db_uio.uio_iovcnt = destidx;
534 534 h->db_uio.uio_iov = &h->db_iov[0];
535 535 h->db_uio.uio_segflg = UIO_SYSSPACE;
536 536 h->db_uio.uio_resid = (size_t)thisio;
537 537
538 538 SET_FPOS(&h->db_uio, xpos);
539 539
540 540 if (!iofn) {
541 541 iofn = nsc_uwrite;
542 542 }
543 543
544 544 rc = (*iofn)(h->db_fd, &h->db_uio, crp);
545 545 if (rc != 0) {
546 546 break;
547 547 }
548 548
549 549 ASSERT(FBA_LEN(thisio) == FBA_NUM(thisio));
550 550 xpos += FBA_LEN(thisio);
551 551 }
552 552
553 553 return (rc);
554 554 }
↓ open down ↓ |
493 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX