]> git.proxmox.com Git - mirror_zfs.git/commitdiff
fix: Uber block label not always found for aux vdevs
authorAmeer Hamza <ahamza@ixsystems.com>
Thu, 4 Jan 2024 14:02:50 +0000 (19:02 +0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 16 Jan 2024 21:17:14 +0000 (13:17 -0800)
When spare or l2cache (aux) vdev is added during pool creation,
spa->spa_uberblock is not dumped until that point. Subsequently,
the aux label is never synchronized after its initial creation,
resulting in the uberblock label remaining undumped. The uberblock
is crucial for lib_blkid in identifying the ZFS partition type. To
address this issue, we now ensure sync of the uberblock label once
if it's not dumped initially.

Reviewed-by: Umer Saleem <usaleem@ixsystems.com>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #15737

include/sys/spa_impl.h
module/zfs/vdev_label.c

index ee91816ac48ef974f13ec93416f0bb8113f919af..0cd0c4720fbefa00277c9815a17367e992997740 100644 (file)
@@ -278,6 +278,7 @@ struct spa {
 
        spa_aux_vdev_t  spa_spares;             /* hot spares */
        spa_aux_vdev_t  spa_l2cache;            /* L2ARC cache devices */
+       boolean_t       spa_aux_sync_uber;      /* need to sync aux uber */
        nvlist_t        *spa_label_features;    /* Features for reading MOS */
        uint64_t        spa_config_object;      /* MOS object for pool config */
        uint64_t        spa_config_generation;  /* config generation number */
index 4c6501cc9a0916bbe444adde540d990fec28fa24..d063747bc55939a4f37d98feda1999ce0c3e966f 100644 (file)
@@ -1156,6 +1156,14 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason)
                 */
                VERIFY(nvlist_add_uint64(label, ZPOOL_CONFIG_ASHIFT,
                    vd->vdev_ashift) == 0);
+
+               /*
+                * When spare or l2cache (aux) vdev is added during pool
+                * creation, spa->spa_uberblock is not written until this
+                * point. Write it on next config sync.
+                */
+               if (uberblock_verify(&spa->spa_uberblock))
+                       spa->spa_aux_sync_uber = B_TRUE;
        } else {
                uint64_t txg = 0ULL;
 
@@ -1794,6 +1802,16 @@ vdev_uberblock_sync_list(vdev_t **svd, int svdcount, uberblock_t *ub, int flags)
        for (int v = 0; v < svdcount; v++)
                vdev_uberblock_sync(zio, &good_writes, ub, svd[v], flags);
 
+       if (spa->spa_aux_sync_uber) {
+               for (int v = 0; v < spa->spa_spares.sav_count; v++) {
+                       vdev_uberblock_sync(zio, &good_writes, ub,
+                           spa->spa_spares.sav_vdevs[v], flags);
+               }
+               for (int v = 0; v < spa->spa_l2cache.sav_count; v++) {
+                       vdev_uberblock_sync(zio, &good_writes, ub,
+                           spa->spa_l2cache.sav_vdevs[v], flags);
+               }
+       }
        (void) zio_wait(zio);
 
        /*
@@ -1808,6 +1826,19 @@ vdev_uberblock_sync_list(vdev_t **svd, int svdcount, uberblock_t *ub, int flags)
                        zio_flush(zio, svd[v]);
                }
        }
+       if (spa->spa_aux_sync_uber) {
+               spa->spa_aux_sync_uber = B_FALSE;
+               for (int v = 0; v < spa->spa_spares.sav_count; v++) {
+                       if (vdev_writeable(spa->spa_spares.sav_vdevs[v])) {
+                               zio_flush(zio, spa->spa_spares.sav_vdevs[v]);
+                       }
+               }
+               for (int v = 0; v < spa->spa_l2cache.sav_count; v++) {
+                       if (vdev_writeable(spa->spa_l2cache.sav_vdevs[v])) {
+                               zio_flush(zio, spa->spa_l2cache.sav_vdevs[v]);
+                       }
+               }
+       }
 
        (void) zio_wait(zio);