vdev_disk.c (236155) | vdev_disk.c (249195) |
---|---|
1/* 2 * CDDL HEADER START 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 --- 6 unchanged lines hidden (view full) --- 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | 1/* 2 * CDDL HEADER START 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 --- 6 unchanged lines hidden (view full) --- 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) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
23 * Copyright (c) 2012 by Delphix. All rights reserved. | 23 * Copyright (c) 2013 by Delphix. All rights reserved. |
24 */ 25 26#include <sys/zfs_context.h> 27#include <sys/spa_impl.h> 28#include <sys/refcount.h> 29#include <sys/vdev_disk.h> 30#include <sys/vdev_impl.h> 31#include <sys/fs/zfs.h> --- 113 unchanged lines hidden (view full) --- 145 dev_t dev; 146 int otyp; 147 148 /* 149 * We must have a pathname, and it must be absolute. 150 */ 151 if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') { 152 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; | 24 */ 25 26#include <sys/zfs_context.h> 27#include <sys/spa_impl.h> 28#include <sys/refcount.h> 29#include <sys/vdev_disk.h> 30#include <sys/vdev_impl.h> 31#include <sys/fs/zfs.h> --- 113 unchanged lines hidden (view full) --- 145 dev_t dev; 146 int otyp; 147 148 /* 149 * We must have a pathname, and it must be absolute. 150 */ 151 if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') { 152 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
153 return (EINVAL); | 153 return (SET_ERROR(EINVAL)); |
154 } 155 156 /* 157 * Reopen the device if it's not currently open. Otherwise, 158 * just update the physical size of the device. 159 */ 160 if (vd->vdev_tsd != NULL) { 161 ASSERT(vd->vdev_reopening); --- 18 unchanged lines hidden (view full) --- 180 * 181 * 3. Otherwise, the device may have moved. Try opening the device 182 * by the devid instead. 183 */ 184 if (vd->vdev_devid != NULL) { 185 if (ddi_devid_str_decode(vd->vdev_devid, &dvd->vd_devid, 186 &dvd->vd_minor) != 0) { 187 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; | 154 } 155 156 /* 157 * Reopen the device if it's not currently open. Otherwise, 158 * just update the physical size of the device. 159 */ 160 if (vd->vdev_tsd != NULL) { 161 ASSERT(vd->vdev_reopening); --- 18 unchanged lines hidden (view full) --- 180 * 181 * 3. Otherwise, the device may have moved. Try opening the device 182 * by the devid instead. 183 */ 184 if (vd->vdev_devid != NULL) { 185 if (ddi_devid_str_decode(vd->vdev_devid, &dvd->vd_devid, 186 &dvd->vd_minor) != 0) { 187 vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL; |
188 return (EINVAL); | 188 return (SET_ERROR(EINVAL)); |
189 } 190 } 191 192 error = EINVAL; /* presume failure */ 193 194 if (vd->vdev_path != NULL) { 195 ddi_devid_t devid; 196 --- 19 unchanged lines hidden (view full) --- 216 &dvd->vd_lh, zfs_li); 217 218 /* 219 * Compare the devid to the stored value. 220 */ 221 if (error == 0 && vd->vdev_devid != NULL && 222 ldi_get_devid(dvd->vd_lh, &devid) == 0) { 223 if (ddi_devid_compare(devid, dvd->vd_devid) != 0) { | 189 } 190 } 191 192 error = EINVAL; /* presume failure */ 193 194 if (vd->vdev_path != NULL) { 195 ddi_devid_t devid; 196 --- 19 unchanged lines hidden (view full) --- 216 &dvd->vd_lh, zfs_li); 217 218 /* 219 * Compare the devid to the stored value. 220 */ 221 if (error == 0 && vd->vdev_devid != NULL && 222 ldi_get_devid(dvd->vd_lh, &devid) == 0) { 223 if (ddi_devid_compare(devid, dvd->vd_devid) != 0) { |
224 error = EINVAL; | 224 error = SET_ERROR(EINVAL); |
225 (void) ldi_close(dvd->vd_lh, spa_mode(spa), 226 kcred); 227 dvd->vd_lh = NULL; 228 } 229 ddi_devid_free(devid); 230 } 231 232 /* --- 65 unchanged lines hidden (view full) --- 298 } 299 300skip_open: 301 /* 302 * Determine the actual size of the device. 303 */ 304 if (ldi_get_size(dvd->vd_lh, psize) != 0) { 305 vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; | 225 (void) ldi_close(dvd->vd_lh, spa_mode(spa), 226 kcred); 227 dvd->vd_lh = NULL; 228 } 229 ddi_devid_free(devid); 230 } 231 232 /* --- 65 unchanged lines hidden (view full) --- 298 } 299 300skip_open: 301 /* 302 * Determine the actual size of the device. 303 */ 304 if (ldi_get_size(dvd->vd_lh, psize) != 0) { 305 vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; |
306 return (EINVAL); | 306 return (SET_ERROR(EINVAL)); |
307 } 308 309 /* 310 * Determine the device's minimum transfer size. 311 * If the ioctl isn't supported, assume DEV_BSIZE. 312 */ 313 if (ldi_ioctl(dvd->vd_lh, DKIOCGMEDIAINFOEXT, (intptr_t)&dkmext, 314 FKIOCTL, kcred, NULL) != 0) --- 54 unchanged lines hidden (view full) --- 369int 370vdev_disk_physio(ldi_handle_t vd_lh, caddr_t data, size_t size, 371 uint64_t offset, int flags) 372{ 373 buf_t *bp; 374 int error = 0; 375 376 if (vd_lh == NULL) | 307 } 308 309 /* 310 * Determine the device's minimum transfer size. 311 * If the ioctl isn't supported, assume DEV_BSIZE. 312 */ 313 if (ldi_ioctl(dvd->vd_lh, DKIOCGMEDIAINFOEXT, (intptr_t)&dkmext, 314 FKIOCTL, kcred, NULL) != 0) --- 54 unchanged lines hidden (view full) --- 369int 370vdev_disk_physio(ldi_handle_t vd_lh, caddr_t data, size_t size, 371 uint64_t offset, int flags) 372{ 373 buf_t *bp; 374 int error = 0; 375 376 if (vd_lh == NULL) |
377 return (EINVAL); | 377 return (SET_ERROR(EINVAL)); |
378 379 ASSERT(flags & B_READ || flags & B_WRITE); 380 381 bp = getrbuf(KM_SLEEP); 382 bp->b_flags = flags | B_BUSY | B_NOCACHE | B_FAILFAST; 383 bp->b_bcount = size; 384 bp->b_un.b_addr = (void *)data; 385 bp->b_lblkno = lbtodb(offset); 386 bp->b_bufsize = size; 387 388 error = ldi_strategy(vd_lh, bp); 389 ASSERT(error == 0); 390 if ((error = biowait(bp)) == 0 && bp->b_resid != 0) | 378 379 ASSERT(flags & B_READ || flags & B_WRITE); 380 381 bp = getrbuf(KM_SLEEP); 382 bp->b_flags = flags | B_BUSY | B_NOCACHE | B_FAILFAST; 383 bp->b_bcount = size; 384 bp->b_un.b_addr = (void *)data; 385 bp->b_lblkno = lbtodb(offset); 386 bp->b_bufsize = size; 387 388 error = ldi_strategy(vd_lh, bp); 389 ASSERT(error == 0); 390 if ((error = biowait(bp)) == 0 && bp->b_resid != 0) |
391 error = EIO; | 391 error = SET_ERROR(EIO); |
392 freerbuf(bp); 393 394 return (error); 395} 396 397static void 398vdev_disk_io_intr(buf_t *bp) 399{ 400 vdev_disk_buf_t *vdb = (vdev_disk_buf_t *)bp; 401 zio_t *zio = vdb->vdb_io; 402 403 /* 404 * The rest of the zio stack only deals with EIO, ECKSUM, and ENXIO. 405 * Rather than teach the rest of the stack about other error 406 * possibilities (EFAULT, etc), we normalize the error value here. 407 */ 408 zio->io_error = (geterror(bp) != 0 ? EIO : 0); 409 410 if (zio->io_error == 0 && bp->b_resid != 0) | 392 freerbuf(bp); 393 394 return (error); 395} 396 397static void 398vdev_disk_io_intr(buf_t *bp) 399{ 400 vdev_disk_buf_t *vdb = (vdev_disk_buf_t *)bp; 401 zio_t *zio = vdb->vdb_io; 402 403 /* 404 * The rest of the zio stack only deals with EIO, ECKSUM, and ENXIO. 405 * Rather than teach the rest of the stack about other error 406 * possibilities (EFAULT, etc), we normalize the error value here. 407 */ 408 zio->io_error = (geterror(bp) != 0 ? EIO : 0); 409 410 if (zio->io_error == 0 && bp->b_resid != 0) |
411 zio->io_error = EIO; | 411 zio->io_error = SET_ERROR(EIO); |
412 413 kmem_free(vdb, sizeof (vdev_disk_buf_t)); 414 415 zio_interrupt(zio); 416} 417 418static void 419vdev_disk_ioctl_free(zio_t *zio) --- 24 unchanged lines hidden (view full) --- 444 vdev_disk_buf_t *vdb; 445 struct dk_callback *dkc; 446 buf_t *bp; 447 int error; 448 449 if (zio->io_type == ZIO_TYPE_IOCTL) { 450 /* XXPOLICY */ 451 if (!vdev_readable(vd)) { | 412 413 kmem_free(vdb, sizeof (vdev_disk_buf_t)); 414 415 zio_interrupt(zio); 416} 417 418static void 419vdev_disk_ioctl_free(zio_t *zio) --- 24 unchanged lines hidden (view full) --- 444 vdev_disk_buf_t *vdb; 445 struct dk_callback *dkc; 446 buf_t *bp; 447 int error; 448 449 if (zio->io_type == ZIO_TYPE_IOCTL) { 450 /* XXPOLICY */ 451 if (!vdev_readable(vd)) { |
452 zio->io_error = ENXIO; | 452 zio->io_error = SET_ERROR(ENXIO); |
453 return (ZIO_PIPELINE_CONTINUE); 454 } 455 456 switch (zio->io_cmd) { 457 458 case DKIOCFLUSHWRITECACHE: 459 460 if (zfs_nocacheflush) 461 break; 462 463 if (vd->vdev_nowritecache) { | 453 return (ZIO_PIPELINE_CONTINUE); 454 } 455 456 switch (zio->io_cmd) { 457 458 case DKIOCFLUSHWRITECACHE: 459 460 if (zfs_nocacheflush) 461 break; 462 463 if (vd->vdev_nowritecache) { |
464 zio->io_error = ENOTSUP; | 464 zio->io_error = SET_ERROR(ENOTSUP); |
465 break; 466 } 467 468 zio->io_vsd = dkc = kmem_alloc(sizeof (*dkc), KM_SLEEP); 469 zio->io_vsd_ops = &vdev_disk_vsd_ops; 470 471 dkc->dkc_callback = vdev_disk_ioctl_done; 472 dkc->dkc_flag = FLUSH_VOLATILE; --- 21 unchanged lines hidden (view full) --- 494 */ 495 vd->vdev_nowritecache = B_TRUE; 496 } 497 zio->io_error = error; 498 499 break; 500 501 default: | 465 break; 466 } 467 468 zio->io_vsd = dkc = kmem_alloc(sizeof (*dkc), KM_SLEEP); 469 zio->io_vsd_ops = &vdev_disk_vsd_ops; 470 471 dkc->dkc_callback = vdev_disk_ioctl_done; 472 dkc->dkc_flag = FLUSH_VOLATILE; --- 21 unchanged lines hidden (view full) --- 494 */ 495 vd->vdev_nowritecache = B_TRUE; 496 } 497 zio->io_error = error; 498 499 break; 500 501 default: |
502 zio->io_error = ENOTSUP; | 502 zio->io_error = SET_ERROR(ENOTSUP); |
503 } 504 505 return (ZIO_PIPELINE_CONTINUE); 506 } 507 508 vdb = kmem_alloc(sizeof (vdev_disk_buf_t), KM_SLEEP); 509 510 vdb->vdb_io = zio; --- 88 unchanged lines hidden (view full) --- 599 } 600 601 if (error && (error = ldi_open_by_name(devpath, FREAD, kcred, &vd_lh, 602 zfs_li))) 603 return (error); 604 605 if (ldi_get_size(vd_lh, &s)) { 606 (void) ldi_close(vd_lh, FREAD, kcred); | 503 } 504 505 return (ZIO_PIPELINE_CONTINUE); 506 } 507 508 vdb = kmem_alloc(sizeof (vdev_disk_buf_t), KM_SLEEP); 509 510 vdb->vdb_io = zio; --- 88 unchanged lines hidden (view full) --- 599 } 600 601 if (error && (error = ldi_open_by_name(devpath, FREAD, kcred, &vd_lh, 602 zfs_li))) 603 return (error); 604 605 if (ldi_get_size(vd_lh, &s)) { 606 (void) ldi_close(vd_lh, FREAD, kcred); |
607 return (EIO); | 607 return (SET_ERROR(EIO)); |
608 } 609 610 size = P2ALIGN_TYPED(s, sizeof (vdev_label_t), uint64_t); 611 label = kmem_alloc(sizeof (vdev_label_t), KM_SLEEP); 612 613 *config = NULL; 614 for (l = 0; l < VDEV_LABELS; l++) { 615 uint64_t offset, state, txg = 0; --- 25 unchanged lines hidden (view full) --- 641 } 642 643 break; 644 } 645 646 kmem_free(label, sizeof (vdev_label_t)); 647 (void) ldi_close(vd_lh, FREAD, kcred); 648 if (*config == NULL) | 608 } 609 610 size = P2ALIGN_TYPED(s, sizeof (vdev_label_t), uint64_t); 611 label = kmem_alloc(sizeof (vdev_label_t), KM_SLEEP); 612 613 *config = NULL; 614 for (l = 0; l < VDEV_LABELS; l++) { 615 uint64_t offset, state, txg = 0; --- 25 unchanged lines hidden (view full) --- 641 } 642 643 break; 644 } 645 646 kmem_free(label, sizeof (vdev_label_t)); 647 (void) ldi_close(vd_lh, FREAD, kcred); 648 if (*config == NULL) |
649 error = EIDRM; | 649 error = SET_ERROR(EIDRM); |
650 651 return (error); 652} | 650 651 return (error); 652} |