@@ -1818,16 +1818,23 @@ vdev_uberblock_load_done(zio_t *zio)
18181818
18191819static void
18201820vdev_uberblock_load_impl (zio_t * * zio , vdev_t * vd , int flags ,
1821- struct ubl_cbdata * cbp , uint32_t * ios )
1821+ struct ubl_cbdata * cbp , uint32_t * ios , boolean_t try_hard )
18221822{
18231823 for (int c = 0 ; c < vd -> vdev_children ; c ++ )
18241824 vdev_uberblock_load_impl (zio , vd -> vdev_child [c ], flags , cbp ,
1825- ios );
1825+ ios , try_hard );
18261826
18271827 if (vd -> vdev_ops -> vdev_op_leaf && vdev_readable (vd ) &&
18281828 vd -> vdev_ops != & vdev_draid_spare_ops ) {
18291829 for (int l = 0 ; l < VDEV_LABELS ; l ++ ) {
1830- for (int n = 0 ; n < VDEV_UBERBLOCK_COUNT (vd ); n ++ ) {
1830+ int n = 0 , lim = VDEV_UBERBLOCK_COUNT (vd );
1831+ if (vd -> vdev_large_label ) {
1832+ if (!try_hard )
1833+ lim = VDEV_UBERBLOCK_SMALL_RING ;
1834+ else
1835+ n = VDEV_UBERBLOCK_SMALL_RING ;
1836+ }
1837+ for (; n < lim ; n ++ ) {
18311838 (* ios )++ ;
18321839 if (* ios > 1 << 16 ) {
18331840 (void ) zio_wait (* zio );
@@ -1863,7 +1870,8 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
18631870
18641871 ASSERT (ub );
18651872 ASSERT (config );
1866-
1873+ boolean_t try_hard = B_FALSE ;
1874+ retry :
18671875 memset (ub , 0 , sizeof (uberblock_t ));
18681876 memset (& cb , 0 , sizeof (cb ));
18691877 * config = NULL ;
@@ -1873,7 +1881,7 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
18731881 spa_config_enter (spa , SCL_ALL , FTAG , RW_WRITER );
18741882 zio = zio_root (spa , NULL , & cb , flags );
18751883 uint32_t ios = 0 ;
1876- vdev_uberblock_load_impl (& zio , rvd , flags , & cb , & ios );
1884+ vdev_uberblock_load_impl (& zio , rvd , flags , & cb , & ios , try_hard );
18771885 (void ) zio_wait (zio );
18781886
18791887 /*
@@ -1912,6 +1920,12 @@ vdev_uberblock_load(vdev_t *rvd, uberblock_t *ub, nvlist_t **config)
19121920 vdev_dbgmsg (cb .ubl_vd , "failed to read label config" );
19131921 }
19141922 }
1923+ if (* config == NULL && rvd -> vdev_large_label && !try_hard ) {
1924+ vdev_dbgmsg (rvd , "failed to read label config. "
1925+ "Trying again without full uberblock ring." );
1926+ try_hard = B_TRUE ;
1927+ goto retry ;
1928+ }
19151929 spa_config_exit (spa , SCL_ALL , FTAG );
19161930}
19171931
@@ -2039,8 +2053,16 @@ vdev_uberblock_sync(zio_t *zio, uint64_t *good_writes,
20392053 * uberblock.
20402054 */
20412055 int m = spa_multihost (vd -> vdev_spa ) ? MMP_BLOCKS_PER_LABEL : 0 ;
2042- int n = (ub -> ub_txg - (RRSS_GET_STATE (ub ) == RRSS_SCRATCH_VALID )) %
2056+ int n = (ub -> ub_txg - (RRSS_GET_STATE (ub ) == RRSS_SCRATCH_VALID ));
2057+ boolean_t update_archive = (n % VDEV_UBERBLOCK_SMALL_RING ) == 0 ;
2058+ int n2 =
2059+ ((n / VDEV_UBERBLOCK_SMALL_RING ) + VDEV_UBERBLOCK_SMALL_RING ) %
20432060 (VDEV_UBERBLOCK_COUNT (vd ) - m );
2061+ if (vd -> vdev_large_label &&
2062+ VDEV_UBERBLOCK_COUNT (vd ) > VDEV_UBERBLOCK_SMALL_RING )
2063+ n %= VDEV_UBERBLOCK_SMALL_RING ;
2064+ else
2065+ n %= VDEV_UBERBLOCK_COUNT (vd ) - m ;
20442066
20452067 /* Copy the uberblock_t into the ABD */
20462068 abd_t * ub_abd = abd_alloc_for_io (VDEV_UBERBLOCK_SIZE (vd ), B_TRUE );
@@ -2062,6 +2084,12 @@ vdev_uberblock_sync(zio_t *zio, uint64_t *good_writes,
20622084 VDEV_UBERBLOCK_OFFSET (vd , n ), VDEV_UBERBLOCK_SIZE (vd ),
20632085 vdev_uberblock_sync_done , good_writes ,
20642086 flags | ZIO_FLAG_DONT_PROPAGATE );
2087+ if (vd -> vdev_large_label && update_archive ) {
2088+ vdev_label_write (zio , vd , l , vd -> vdev_large_label ,
2089+ ub_abd , VDEV_UBERBLOCK_OFFSET (vd , n2 ),
2090+ VDEV_UBERBLOCK_SIZE (vd ), vdev_uberblock_sync_done ,
2091+ good_writes , flags | ZIO_FLAG_DONT_PROPAGATE );
2092+ }
20652093 }
20662094
20672095 abd_free (ub_abd );
@@ -2288,15 +2316,14 @@ vdev_label_sync(zio_t *zio, uint64_t *good_writes,
22882316 buflen = sizeof (vp -> vp_nvlist );
22892317
22902318 if (!nvlist_pack (label , & buf , & buflen , NV_ENCODE_XDR , KM_SLEEP )) {
2291- vdev_label_sync_large (vd , zio , good_writes ,
2292- l , flags , sc_abd , vp_abd );
2319+ vdev_label_sync_large (vd , zio , good_writes , l , flags , sc_abd ,
2320+ vp_abd );
22932321 for (; l < VDEV_LABELS &&
22942322 !(vd -> vdev_large_label && l >= (VDEV_LABELS / 2 )); l += 2 ) {
22952323 vdev_label_write (zio , vd , l , B_FALSE , vp_abd ,
22962324 offsetof(vdev_label_t , vl_vdev_phys ),
2297- sizeof (vdev_phys_t ),
2298- vdev_label_sync_done , good_writes ,
2299- flags | ZIO_FLAG_DONT_PROPAGATE );
2325+ sizeof (vdev_phys_t ), vdev_label_sync_done ,
2326+ good_writes , flags | ZIO_FLAG_DONT_PROPAGATE );
23002327 }
23012328 }
23022329
0 commit comments