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