zfsimpl.c (200309) | zfsimpl.c (201689) |
---|---|
1/*- 2 * Copyright (c) 2007 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2007 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/boot/zfs/zfsimpl.c 200309 2009-12-09 20:36:56Z jhb $"); | 28__FBSDID("$FreeBSD: head/sys/boot/zfs/zfsimpl.c 201689 2010-01-06 23:09:23Z delphij $"); |
29 30/* 31 * Stand-alone ZFS file reader. 32 */ 33 34#include "zfsimpl.h" 35#include "zfssubr.c" 36 --- 362 unchanged lines hidden (view full) --- 399 vdev->v_phys_read = 0; 400 vdev->v_read_priv = 0; 401 STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink); 402 403 return (vdev); 404} 405 406static int | 29 30/* 31 * Stand-alone ZFS file reader. 32 */ 33 34#include "zfsimpl.h" 35#include "zfssubr.c" 36 --- 362 unchanged lines hidden (view full) --- 399 vdev->v_phys_read = 0; 400 vdev->v_read_priv = 0; 401 STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink); 402 403 return (vdev); 404} 405 406static int |
407vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp) | 407vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp, int is_newer) |
408{ 409 int rc; 410 uint64_t guid, id, ashift, nparity; 411 const char *type; 412 const char *path; 413 vdev_t *vdev, *kid; 414 const unsigned char *kids; | 408{ 409 int rc; 410 uint64_t guid, id, ashift, nparity; 411 const char *type; 412 const char *path; 413 vdev_t *vdev, *kid; 414 const unsigned char *kids; |
415 int nkids, i; | 415 int nkids, i, is_new; 416 uint64_t is_offline, is_faulted, is_degraded, is_removed; |
416 417 if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID, 418 DATA_TYPE_UINT64, 0, &guid) 419 || nvlist_find(nvlist, ZPOOL_CONFIG_ID, 420 DATA_TYPE_UINT64, 0, &id) 421 || nvlist_find(nvlist, ZPOOL_CONFIG_TYPE, 422 DATA_TYPE_STRING, 0, &type)) { 423 printf("ZFS: can't find vdev details\n"); 424 return (ENOENT); 425 } 426 | 417 418 if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID, 419 DATA_TYPE_UINT64, 0, &guid) 420 || nvlist_find(nvlist, ZPOOL_CONFIG_ID, 421 DATA_TYPE_UINT64, 0, &id) 422 || nvlist_find(nvlist, ZPOOL_CONFIG_TYPE, 423 DATA_TYPE_STRING, 0, &type)) { 424 printf("ZFS: can't find vdev details\n"); 425 return (ENOENT); 426 } 427 |
427 /* 428 * Assume that if we've seen this vdev tree before, this one 429 * will be identical. 430 */ 431 vdev = vdev_find(guid); 432 if (vdev) { 433 if (vdevp) 434 *vdevp = vdev; 435 return (0); 436 } 437 | |
438 if (strcmp(type, VDEV_TYPE_MIRROR) 439 && strcmp(type, VDEV_TYPE_DISK) 440 && strcmp(type, VDEV_TYPE_RAIDZ)) { 441 printf("ZFS: can only boot from disk, mirror or raidz vdevs\n"); 442 return (EIO); 443 } 444 | 428 if (strcmp(type, VDEV_TYPE_MIRROR) 429 && strcmp(type, VDEV_TYPE_DISK) 430 && strcmp(type, VDEV_TYPE_RAIDZ)) { 431 printf("ZFS: can only boot from disk, mirror or raidz vdevs\n"); 432 return (EIO); 433 } 434 |
435 is_offline = is_removed = is_faulted = is_degraded = 0; 436 437 nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, 0, 438 &is_offline); 439 nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, 0, 440 &is_removed); 441 nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, 0, 442 &is_faulted); 443 nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, 0, 444 &is_degraded); 445 446 vdev = vdev_find(guid); 447 if (!vdev) { 448 is_new = 1; 449 |
|
445 if (!strcmp(type, VDEV_TYPE_MIRROR)) 446 vdev = vdev_create(guid, vdev_mirror_read); 447 else if (!strcmp(type, VDEV_TYPE_RAIDZ)) 448 vdev = vdev_create(guid, vdev_raidz_read); 449 else 450 vdev = vdev_create(guid, vdev_disk_read); 451 452 vdev->v_id = id; --- 22 unchanged lines hidden (view full) --- 475 if (vdev->v_nparity == 1) 476 vdev->v_name = "raidz1"; 477 else 478 vdev->v_name = "raidz2"; 479 } else { 480 vdev->v_name = strdup(type); 481 } 482 } | 450 if (!strcmp(type, VDEV_TYPE_MIRROR)) 451 vdev = vdev_create(guid, vdev_mirror_read); 452 else if (!strcmp(type, VDEV_TYPE_RAIDZ)) 453 vdev = vdev_create(guid, vdev_raidz_read); 454 else 455 vdev = vdev_create(guid, vdev_disk_read); 456 457 vdev->v_id = id; --- 22 unchanged lines hidden (view full) --- 480 if (vdev->v_nparity == 1) 481 vdev->v_name = "raidz1"; 482 else 483 vdev->v_name = "raidz2"; 484 } else { 485 vdev->v_name = strdup(type); 486 } 487 } |
488 489 if (is_offline) 490 vdev->v_state = VDEV_STATE_OFFLINE; 491 else if (is_removed) 492 vdev->v_state = VDEV_STATE_REMOVED; 493 else if (is_faulted) 494 vdev->v_state = VDEV_STATE_FAULTED; 495 else if (is_degraded) 496 vdev->v_state = VDEV_STATE_DEGRADED; 497 else 498 vdev->v_state = VDEV_STATE_HEALTHY; 499 } else { 500 is_new = 0; 501 502 if (is_newer) { 503 /* 504 * We've already seen this vdev, but from an older 505 * vdev label, so let's refresh its state from the 506 * newer label. 507 */ 508 if (is_offline) 509 vdev->v_state = VDEV_STATE_OFFLINE; 510 else if (is_removed) 511 vdev->v_state = VDEV_STATE_REMOVED; 512 else if (is_faulted) 513 vdev->v_state = VDEV_STATE_FAULTED; 514 else if (is_degraded) 515 vdev->v_state = VDEV_STATE_DEGRADED; 516 else 517 vdev->v_state = VDEV_STATE_HEALTHY; 518 } 519 } 520 |
|
483 rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, 484 DATA_TYPE_NVLIST_ARRAY, &nkids, &kids); 485 /* 486 * Its ok if we don't have any kids. 487 */ 488 if (rc == 0) { 489 vdev->v_nchildren = nkids; 490 for (i = 0; i < nkids; i++) { | 521 rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, 522 DATA_TYPE_NVLIST_ARRAY, &nkids, &kids); 523 /* 524 * Its ok if we don't have any kids. 525 */ 526 if (rc == 0) { 527 vdev->v_nchildren = nkids; 528 for (i = 0; i < nkids; i++) { |
491 rc = vdev_init_from_nvlist(kids, &kid); | 529 rc = vdev_init_from_nvlist(kids, &kid, is_newer); |
492 if (rc) 493 return (rc); | 530 if (rc) 531 return (rc); |
494 STAILQ_INSERT_TAIL(&vdev->v_children, kid, v_childlink); | 532 if (is_new) 533 STAILQ_INSERT_TAIL(&vdev->v_children, kid, 534 v_childlink); |
495 kids = nvlist_next(kids); 496 } 497 } else { 498 vdev->v_nchildren = 0; 499 } 500 501 if (vdevp) 502 *vdevp = vdev; --- 85 unchanged lines hidden (view full) --- 588 589static const char * 590state_name(vdev_state_t state) 591{ 592 static const char* names[] = { 593 "UNKNOWN", 594 "CLOSED", 595 "OFFLINE", | 535 kids = nvlist_next(kids); 536 } 537 } else { 538 vdev->v_nchildren = 0; 539 } 540 541 if (vdevp) 542 *vdevp = vdev; --- 85 unchanged lines hidden (view full) --- 628 629static const char * 630state_name(vdev_state_t state) 631{ 632 static const char* names[] = { 633 "UNKNOWN", 634 "CLOSED", 635 "OFFLINE", |
636 "REMOVED", |
|
596 "CANT_OPEN", | 637 "CANT_OPEN", |
638 "FAULTED", |
|
597 "DEGRADED", 598 "ONLINE" 599 }; 600 return names[state]; 601} 602 603#ifdef BOOT2 604 --- 101 unchanged lines hidden (view full) --- 706 off_t off; 707 blkptr_t bp; 708 const unsigned char *nvlist; 709 uint64_t val; 710 uint64_t guid; 711 uint64_t pool_txg, pool_guid; 712 const char *pool_name; 713 const unsigned char *vdevs; | 639 "DEGRADED", 640 "ONLINE" 641 }; 642 return names[state]; 643} 644 645#ifdef BOOT2 646 --- 101 unchanged lines hidden (view full) --- 748 off_t off; 749 blkptr_t bp; 750 const unsigned char *nvlist; 751 uint64_t val; 752 uint64_t guid; 753 uint64_t pool_txg, pool_guid; 754 const char *pool_name; 755 const unsigned char *vdevs; |
714 int i, rc; | 756 int i, rc, is_newer; |
715 char upbuf[1024]; 716 const struct uberblock *up; 717 718 /* 719 * Load the vdev label and figure out which 720 * uberblock is most current. 721 */ 722 memset(&vtmp, 0, sizeof(vtmp)); --- 65 unchanged lines hidden (view full) --- 788 /* 789 * Create the pool if this is the first time we've seen it. 790 */ 791 spa = spa_find_by_guid(pool_guid); 792 if (!spa) { 793 spa = spa_create(pool_guid); 794 spa->spa_name = strdup(pool_name); 795 } | 757 char upbuf[1024]; 758 const struct uberblock *up; 759 760 /* 761 * Load the vdev label and figure out which 762 * uberblock is most current. 763 */ 764 memset(&vtmp, 0, sizeof(vtmp)); --- 65 unchanged lines hidden (view full) --- 830 /* 831 * Create the pool if this is the first time we've seen it. 832 */ 833 spa = spa_find_by_guid(pool_guid); 834 if (!spa) { 835 spa = spa_create(pool_guid); 836 spa->spa_name = strdup(pool_name); 837 } |
796 if (pool_txg > spa->spa_txg) | 838 if (pool_txg > spa->spa_txg) { |
797 spa->spa_txg = pool_txg; | 839 spa->spa_txg = pool_txg; |
840 is_newer = 1; 841 } else 842 is_newer = 0; |
|
798 799 /* 800 * Get the vdev tree and create our in-core copy of it. | 843 844 /* 845 * Get the vdev tree and create our in-core copy of it. |
801 * If we already have a healthy vdev with this guid, this must | 846 * If we already have a vdev with this guid, this must |
802 * be some kind of alias (overlapping slices, dangerously dedicated 803 * disks etc). 804 */ 805 if (nvlist_find(nvlist, 806 ZPOOL_CONFIG_GUID, 807 DATA_TYPE_UINT64, 0, &guid)) { 808 return (EIO); 809 } 810 vdev = vdev_find(guid); | 847 * be some kind of alias (overlapping slices, dangerously dedicated 848 * disks etc). 849 */ 850 if (nvlist_find(nvlist, 851 ZPOOL_CONFIG_GUID, 852 DATA_TYPE_UINT64, 0, &guid)) { 853 return (EIO); 854 } 855 vdev = vdev_find(guid); |
811 if (vdev && vdev->v_state == VDEV_STATE_HEALTHY) { | 856 if (vdev && vdev->v_phys_read) /* Has this vdev already been inited? */ |
812 return (EIO); | 857 return (EIO); |
813 } | |
814 815 if (nvlist_find(nvlist, 816 ZPOOL_CONFIG_VDEV_TREE, 817 DATA_TYPE_NVLIST, 0, &vdevs)) { 818 return (EIO); 819 } | 858 859 if (nvlist_find(nvlist, 860 ZPOOL_CONFIG_VDEV_TREE, 861 DATA_TYPE_NVLIST, 0, &vdevs)) { 862 return (EIO); 863 } |
820 rc = vdev_init_from_nvlist(vdevs, &top_vdev); | 864 865 rc = vdev_init_from_nvlist(vdevs, &top_vdev, is_newer); |
821 if (rc) 822 return (rc); 823 824 /* 825 * Add the toplevel vdev to the pool if its not already there. 826 */ 827 STAILQ_FOREACH(pool_vdev, &spa->spa_vdevs, v_childlink) 828 if (top_vdev == pool_vdev) --- 4 unchanged lines hidden (view full) --- 833 /* 834 * We should already have created an incomplete vdev for this 835 * vdev. Find it and initialise it with our read proc. 836 */ 837 vdev = vdev_find(guid); 838 if (vdev) { 839 vdev->v_phys_read = read; 840 vdev->v_read_priv = read_priv; | 866 if (rc) 867 return (rc); 868 869 /* 870 * Add the toplevel vdev to the pool if its not already there. 871 */ 872 STAILQ_FOREACH(pool_vdev, &spa->spa_vdevs, v_childlink) 873 if (top_vdev == pool_vdev) --- 4 unchanged lines hidden (view full) --- 878 /* 879 * We should already have created an incomplete vdev for this 880 * vdev. Find it and initialise it with our read proc. 881 */ 882 vdev = vdev_find(guid); 883 if (vdev) { 884 vdev->v_phys_read = read; 885 vdev->v_read_priv = read_priv; |
841 vdev->v_state = VDEV_STATE_HEALTHY; | |
842 } else { 843 printf("ZFS: inconsistent nvlist contents\n"); 844 return (EIO); 845 } 846 847 /* 848 * Re-evaluate top-level vdev state. 849 */ --- 708 unchanged lines hidden --- | 886 } else { 887 printf("ZFS: inconsistent nvlist contents\n"); 888 return (EIO); 889 } 890 891 /* 892 * Re-evaluate top-level vdev state. 893 */ --- 708 unchanged lines hidden --- |