Deleted Added
full compact
vdev_label.c (185029) vdev_label.c (209962)
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

--- 5 unchanged lines hidden (view full) ---

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/*
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

--- 5 unchanged lines hidden (view full) ---

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 2008 Sun Microsystems, Inc. All rights reserved.
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*
27 * Virtual Device Labels
28 * ---------------------
29 *
30 * The vdev label serves several distinct purposes:

--- 197 unchanged lines hidden (view full) ---

228 if (vd->vdev_devid != NULL)
229 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_DEVID,
230 vd->vdev_devid) == 0);
231
232 if (vd->vdev_physpath != NULL)
233 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
234 vd->vdev_physpath) == 0);
235
23 * Use is subject to license terms.
24 */
25
26/*
27 * Virtual Device Labels
28 * ---------------------
29 *
30 * The vdev label serves several distinct purposes:

--- 197 unchanged lines hidden (view full) ---

228 if (vd->vdev_devid != NULL)
229 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_DEVID,
230 vd->vdev_devid) == 0);
231
232 if (vd->vdev_physpath != NULL)
233 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_PHYS_PATH,
234 vd->vdev_physpath) == 0);
235
236 if (vd->vdev_fru != NULL)
237 VERIFY(nvlist_add_string(nv, ZPOOL_CONFIG_FRU,
238 vd->vdev_fru) == 0);
239
236 if (vd->vdev_nparity != 0) {
237 ASSERT(strcmp(vd->vdev_ops->vdev_op_type,
238 VDEV_TYPE_RAIDZ) == 0);
239
240 /*
241 * Make sure someone hasn't managed to sneak a fancy new vdev
242 * into a crufty old storage pool.
243 */

--- 28 unchanged lines hidden (view full) ---

272 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ASHIFT,
273 vd->vdev_ashift) == 0);
274 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ASIZE,
275 vd->vdev_asize) == 0);
276 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_IS_LOG,
277 vd->vdev_islog) == 0);
278 }
279
240 if (vd->vdev_nparity != 0) {
241 ASSERT(strcmp(vd->vdev_ops->vdev_op_type,
242 VDEV_TYPE_RAIDZ) == 0);
243
244 /*
245 * Make sure someone hasn't managed to sneak a fancy new vdev
246 * into a crufty old storage pool.
247 */

--- 28 unchanged lines hidden (view full) ---

276 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ASHIFT,
277 vd->vdev_ashift) == 0);
278 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_ASIZE,
279 vd->vdev_asize) == 0);
280 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_IS_LOG,
281 vd->vdev_islog) == 0);
282 }
283
280 if (vd->vdev_dtl.smo_object != 0)
284 if (vd->vdev_dtl_smo.smo_object != 0)
281 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_DTL,
285 VERIFY(nvlist_add_uint64(nv, ZPOOL_CONFIG_DTL,
282 vd->vdev_dtl.smo_object) == 0);
286 vd->vdev_dtl_smo.smo_object) == 0);
283
284 if (getstats) {
285 vdev_stat_t vs;
286 vdev_get_stats(vd, &vs);
287 VERIFY(nvlist_add_uint64_array(nv, ZPOOL_CONFIG_STATS,
288 (uint64_t *)&vs, sizeof (vs) / sizeof (uint64_t)) == 0);
289 }
290

--- 192 unchanged lines hidden (view full) ---

483 * itself.
484 */
485int
486vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
487{
488 spa_t *spa = vd->vdev_spa;
489 nvlist_t *label;
490 vdev_phys_t *vp;
287
288 if (getstats) {
289 vdev_stat_t vs;
290 vdev_get_stats(vd, &vs);
291 VERIFY(nvlist_add_uint64_array(nv, ZPOOL_CONFIG_STATS,
292 (uint64_t *)&vs, sizeof (vs) / sizeof (uint64_t)) == 0);
293 }
294

--- 192 unchanged lines hidden (view full) ---

487 * itself.
488 */
489int
490vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
491{
492 spa_t *spa = vd->vdev_spa;
493 nvlist_t *label;
494 vdev_phys_t *vp;
491 vdev_boot_header_t *vb;
495 char *pad2;
492 uberblock_t *ub;
493 zio_t *zio;
494 char *buf;
495 size_t buflen;
496 int error;
497 uint64_t spare_guid, l2cache_guid;
498 int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
499

--- 15 unchanged lines hidden (view full) ---

515
516 /*
517 * Determine if the vdev is in use.
518 */
519 if (reason != VDEV_LABEL_REMOVE &&
520 vdev_inuse(vd, crtxg, reason, &spare_guid, &l2cache_guid))
521 return (EBUSY);
522
496 uberblock_t *ub;
497 zio_t *zio;
498 char *buf;
499 size_t buflen;
500 int error;
501 uint64_t spare_guid, l2cache_guid;
502 int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
503

--- 15 unchanged lines hidden (view full) ---

519
520 /*
521 * Determine if the vdev is in use.
522 */
523 if (reason != VDEV_LABEL_REMOVE &&
524 vdev_inuse(vd, crtxg, reason, &spare_guid, &l2cache_guid))
525 return (EBUSY);
526
523 ASSERT(reason != VDEV_LABEL_REMOVE ||
524 vdev_inuse(vd, crtxg, reason, NULL, NULL));
525
526 /*
527 * If this is a request to add or replace a spare or l2cache device
528 * that is in use elsewhere on the system, then we must update the
529 * guid (which was initialized to a random value) to reflect the
530 * actual GUID (which is shared between multiple pools).
531 */
532 if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_L2CACHE &&
533 spare_guid != 0ULL) {

--- 94 unchanged lines hidden (view full) ---

628 if (error != 0) {
629 nvlist_free(label);
630 zio_buf_free(vp, sizeof (vdev_phys_t));
631 /* EFAULT means nvlist_pack ran out of room */
632 return (error == EFAULT ? ENAMETOOLONG : EINVAL);
633 }
634
635 /*
527 /*
528 * If this is a request to add or replace a spare or l2cache device
529 * that is in use elsewhere on the system, then we must update the
530 * guid (which was initialized to a random value) to reflect the
531 * actual GUID (which is shared between multiple pools).
532 */
533 if (reason != VDEV_LABEL_REMOVE && reason != VDEV_LABEL_L2CACHE &&
534 spare_guid != 0ULL) {

--- 94 unchanged lines hidden (view full) ---

629 if (error != 0) {
630 nvlist_free(label);
631 zio_buf_free(vp, sizeof (vdev_phys_t));
632 /* EFAULT means nvlist_pack ran out of room */
633 return (error == EFAULT ? ENAMETOOLONG : EINVAL);
634 }
635
636 /*
636 * Initialize boot block header.
637 */
638 vb = zio_buf_alloc(sizeof (vdev_boot_header_t));
639 bzero(vb, sizeof (vdev_boot_header_t));
640 vb->vb_magic = VDEV_BOOT_MAGIC;
641 vb->vb_version = VDEV_BOOT_VERSION;
642 vb->vb_offset = VDEV_BOOT_OFFSET;
643 vb->vb_size = VDEV_BOOT_SIZE;
644
645 /*
646 * Initialize uberblock template.
647 */
648 ub = zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd));
649 bzero(ub, VDEV_UBERBLOCK_SIZE(vd));
650 *ub = spa->spa_uberblock;
651 ub->ub_txg = 0;
652
637 * Initialize uberblock template.
638 */
639 ub = zio_buf_alloc(VDEV_UBERBLOCK_SIZE(vd));
640 bzero(ub, VDEV_UBERBLOCK_SIZE(vd));
641 *ub = spa->spa_uberblock;
642 ub->ub_txg = 0;
643
644 /* Initialize the 2nd padding area. */
645 pad2 = zio_buf_alloc(VDEV_PAD_SIZE);
646 bzero(pad2, VDEV_PAD_SIZE);
647
653 /*
654 * Write everything in parallel.
655 */
656 zio = zio_root(spa, NULL, NULL, flags);
657
658 for (int l = 0; l < VDEV_LABELS; l++) {
659
660 vdev_label_write(zio, vd, l, vp,
661 offsetof(vdev_label_t, vl_vdev_phys),
662 sizeof (vdev_phys_t), NULL, NULL, flags);
663
648 /*
649 * Write everything in parallel.
650 */
651 zio = zio_root(spa, NULL, NULL, flags);
652
653 for (int l = 0; l < VDEV_LABELS; l++) {
654
655 vdev_label_write(zio, vd, l, vp,
656 offsetof(vdev_label_t, vl_vdev_phys),
657 sizeof (vdev_phys_t), NULL, NULL, flags);
658
664 vdev_label_write(zio, vd, l, vb,
665 offsetof(vdev_label_t, vl_boot_header),
666 sizeof (vdev_boot_header_t), NULL, NULL, flags);
659 /*
660 * Skip the 1st padding area.
661 * Zero out the 2nd padding area where it might have
662 * left over data from previous filesystem format.
663 */
664 vdev_label_write(zio, vd, l, pad2,
665 offsetof(vdev_label_t, vl_pad2),
666 VDEV_PAD_SIZE, NULL, NULL, flags);
667
668 for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) {
669 vdev_label_write(zio, vd, l, ub,
670 VDEV_UBERBLOCK_OFFSET(vd, n),
671 VDEV_UBERBLOCK_SIZE(vd), NULL, NULL, flags);
672 }
673 }
674
675 error = zio_wait(zio);
676
677 nvlist_free(label);
667
668 for (int n = 0; n < VDEV_UBERBLOCK_COUNT(vd); n++) {
669 vdev_label_write(zio, vd, l, ub,
670 VDEV_UBERBLOCK_OFFSET(vd, n),
671 VDEV_UBERBLOCK_SIZE(vd), NULL, NULL, flags);
672 }
673 }
674
675 error = zio_wait(zio);
676
677 nvlist_free(label);
678 zio_buf_free(pad2, VDEV_PAD_SIZE);
678 zio_buf_free(ub, VDEV_UBERBLOCK_SIZE(vd));
679 zio_buf_free(ub, VDEV_UBERBLOCK_SIZE(vd));
679 zio_buf_free(vb, sizeof (vdev_boot_header_t));
680 zio_buf_free(vp, sizeof (vdev_phys_t));
681
682 /*
683 * If this vdev hasn't been previously identified as a spare, then we
684 * mark it as such only if a) we are labeling it as a spare, or b) it
685 * exists as a spare elsewhere in the system. Do the same for
686 * level 2 ARC devices.
687 */

--- 12 unchanged lines hidden (view full) ---

700
701/*
702 * ==========================================================================
703 * uberblock load/sync
704 * ==========================================================================
705 */
706
707/*
680 zio_buf_free(vp, sizeof (vdev_phys_t));
681
682 /*
683 * If this vdev hasn't been previously identified as a spare, then we
684 * mark it as such only if a) we are labeling it as a spare, or b) it
685 * exists as a spare elsewhere in the system. Do the same for
686 * level 2 ARC devices.
687 */

--- 12 unchanged lines hidden (view full) ---

700
701/*
702 * ==========================================================================
703 * uberblock load/sync
704 * ==========================================================================
705 */
706
707/*
708 * For use by zdb and debugging purposes only
709 */
710uint64_t ub_max_txg = UINT64_MAX;
711
712/*
708 * Consider the following situation: txg is safely synced to disk. We've
709 * written the first uberblock for txg + 1, and then we lose power. When we
710 * come back up, we fail to see the uberblock for txg + 1 because, say,
711 * it was on a mirrored device and the replica to which we wrote txg + 1
712 * is now offline. If we then make some changes and sync txg + 1, and then
713 * the missing replica comes back, then for a new seconds we'll have two
714 * conflicting uberblocks on disk with the same txg. The solution is simple:
715 * among uberblocks with equal txg, choose the one with the latest timestamp.

--- 20 unchanged lines hidden (view full) ---

736 zio_t *rio = zio->io_private;
737 uberblock_t *ub = zio->io_data;
738 uberblock_t *ubbest = rio->io_private;
739
740 ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(zio->io_vd));
741
742 if (zio->io_error == 0 && uberblock_verify(ub) == 0) {
743 mutex_enter(&rio->io_lock);
713 * Consider the following situation: txg is safely synced to disk. We've
714 * written the first uberblock for txg + 1, and then we lose power. When we
715 * come back up, we fail to see the uberblock for txg + 1 because, say,
716 * it was on a mirrored device and the replica to which we wrote txg + 1
717 * is now offline. If we then make some changes and sync txg + 1, and then
718 * the missing replica comes back, then for a new seconds we'll have two
719 * conflicting uberblocks on disk with the same txg. The solution is simple:
720 * among uberblocks with equal txg, choose the one with the latest timestamp.

--- 20 unchanged lines hidden (view full) ---

741 zio_t *rio = zio->io_private;
742 uberblock_t *ub = zio->io_data;
743 uberblock_t *ubbest = rio->io_private;
744
745 ASSERT3U(zio->io_size, ==, VDEV_UBERBLOCK_SIZE(zio->io_vd));
746
747 if (zio->io_error == 0 && uberblock_verify(ub) == 0) {
748 mutex_enter(&rio->io_lock);
744 if (vdev_uberblock_compare(ub, ubbest) > 0)
749 if (ub->ub_txg <= ub_max_txg &&
750 vdev_uberblock_compare(ub, ubbest) > 0)
745 *ubbest = *ub;
746 mutex_exit(&rio->io_lock);
747 }
748
749 zio_buf_free(zio->io_data, zio->io_size);
750}
751
752void

--- 200 unchanged lines hidden (view full) ---

953 /*
954 * Write the new labels to disk.
955 */
956 zio = zio_root(spa, NULL, NULL, flags);
957
958 for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd)) {
959 uint64_t *good_writes = kmem_zalloc(sizeof (uint64_t),
960 KM_SLEEP);
751 *ubbest = *ub;
752 mutex_exit(&rio->io_lock);
753 }
754
755 zio_buf_free(zio->io_data, zio->io_size);
756}
757
758void

--- 200 unchanged lines hidden (view full) ---

959 /*
960 * Write the new labels to disk.
961 */
962 zio = zio_root(spa, NULL, NULL, flags);
963
964 for (vd = list_head(dl); vd != NULL; vd = list_next(dl, vd)) {
965 uint64_t *good_writes = kmem_zalloc(sizeof (uint64_t),
966 KM_SLEEP);
961 zio_t *vio = zio_null(zio, spa,
967 zio_t *vio = zio_null(zio, spa, NULL,
962 (vd->vdev_islog || vd->vdev_aux != NULL) ?
963 vdev_label_sync_ignore_done : vdev_label_sync_top_done,
964 good_writes, flags);
965 vdev_label_sync(vio, vd, l, txg, flags);
966 zio_nowait(vio);
967 }
968
969 error = zio_wait(zio);

--- 109 unchanged lines hidden ---
968 (vd->vdev_islog || vd->vdev_aux != NULL) ?
969 vdev_label_sync_ignore_done : vdev_label_sync_top_done,
970 good_writes, flags);
971 vdev_label_sync(vio, vd, l, txg, flags);
972 zio_nowait(vio);
973 }
974
975 error = zio_wait(zio);

--- 109 unchanged lines hidden ---