Print this page
4932 vdev incorrectly expanding on last mirror child -> top-level vdev
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


 770         ASSERT(mvd->vdev_children == 1);
 771         ASSERT(mvd->vdev_ops == &vdev_mirror_ops ||
 772             mvd->vdev_ops == &vdev_replacing_ops ||
 773             mvd->vdev_ops == &vdev_spare_ops);
 774         cvd->vdev_ashift = mvd->vdev_ashift;
 775 
 776         vdev_remove_child(mvd, cvd);
 777         vdev_remove_child(pvd, mvd);
 778 
 779         /*
 780          * If cvd will replace mvd as a top-level vdev, preserve mvd's guid.
 781          * Otherwise, we could have detached an offline device, and when we
 782          * go to import the pool we'll think we have two top-level vdevs,
 783          * instead of a different version of the same top-level vdev.
 784          */
 785         if (mvd->vdev_top == mvd) {
 786                 uint64_t guid_delta = mvd->vdev_guid - cvd->vdev_guid;
 787                 cvd->vdev_orig_guid = cvd->vdev_guid;
 788                 cvd->vdev_guid += guid_delta;
 789                 cvd->vdev_guid_sum += guid_delta;











 790         }
 791         cvd->vdev_id = mvd->vdev_id;
 792         vdev_add_child(pvd, cvd);
 793         vdev_top_update(cvd->vdev_top, cvd->vdev_top);
 794 
 795         if (cvd == cvd->vdev_top)
 796                 vdev_top_transfer(mvd, cvd);
 797 
 798         ASSERT(mvd->vdev_children == 0);
 799         vdev_free(mvd);
 800 }
 801 
 802 int
 803 vdev_metaslab_init(vdev_t *vd, uint64_t txg)
 804 {
 805         spa_t *spa = vd->vdev_spa;
 806         objset_t *mos = spa->spa_meta_objset;
 807         uint64_t m;
 808         uint64_t oldc = vd->vdev_ms_count;
 809         uint64_t newc = vd->vdev_asize >> vd->vdev_ms_shift;




 770         ASSERT(mvd->vdev_children == 1);
 771         ASSERT(mvd->vdev_ops == &vdev_mirror_ops ||
 772             mvd->vdev_ops == &vdev_replacing_ops ||
 773             mvd->vdev_ops == &vdev_spare_ops);
 774         cvd->vdev_ashift = mvd->vdev_ashift;
 775 
 776         vdev_remove_child(mvd, cvd);
 777         vdev_remove_child(pvd, mvd);
 778 
 779         /*
 780          * If cvd will replace mvd as a top-level vdev, preserve mvd's guid.
 781          * Otherwise, we could have detached an offline device, and when we
 782          * go to import the pool we'll think we have two top-level vdevs,
 783          * instead of a different version of the same top-level vdev.
 784          */
 785         if (mvd->vdev_top == mvd) {
 786                 uint64_t guid_delta = mvd->vdev_guid - cvd->vdev_guid;
 787                 cvd->vdev_orig_guid = cvd->vdev_guid;
 788                 cvd->vdev_guid += guid_delta;
 789                 cvd->vdev_guid_sum += guid_delta;
 790 
 791                 /*
 792                  * If pool not set for autoexpand, we need to also preserve
 793                  * mvd's asize to prevent automatic expansion of cvd.
 794                  * Otherwise if we are adjusting the mirror by attaching and
 795                  * detaching children of non-uniform sizes, the mirror could
 796                  * autoexpand, unexpectedly requiring larger devices to
 797                  * re-establish the mirror.
 798                  */
 799                 if (!cvd->vdev_spa->spa_autoexpand)
 800                         cvd->vdev_asize = mvd->vdev_asize;
 801         }
 802         cvd->vdev_id = mvd->vdev_id;
 803         vdev_add_child(pvd, cvd);
 804         vdev_top_update(cvd->vdev_top, cvd->vdev_top);
 805 
 806         if (cvd == cvd->vdev_top)
 807                 vdev_top_transfer(mvd, cvd);
 808 
 809         ASSERT(mvd->vdev_children == 0);
 810         vdev_free(mvd);
 811 }
 812 
 813 int
 814 vdev_metaslab_init(vdev_t *vd, uint64_t txg)
 815 {
 816         spa_t *spa = vd->vdev_spa;
 817         objset_t *mos = spa->spa_meta_objset;
 818         uint64_t m;
 819         uint64_t oldc = vd->vdev_ms_count;
 820         uint64_t newc = vd->vdev_asize >> vd->vdev_ms_shift;