Page MenuHomeFreeBSD

D20319.diff
No OneTemporary

D20319.diff

Index: stand/libsa/zfs/zfsimpl.c
===================================================================
--- stand/libsa/zfs/zfsimpl.c
+++ stand/libsa/zfs/zfsimpl.c
@@ -78,6 +78,7 @@
static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr;
#define TEMP_SIZE (1024 * 1024)
+#define ALL_LABELS_INVALID ((int)0xFFFFFFFF)
static int zio_read(const spa_t *spa, const blkptr_t *bp, void *buf);
static int zfs_get_root(const spa_t *spa, uint64_t *objid);
@@ -513,6 +514,20 @@
return (vdev);
}
+static void
+vdev_delete_by_guid(uint64_t guid)
+{
+ vdev_t *dev, *kid;
+
+ if(dev = vdev_find(guid)) {
+ STAILQ_FOREACH(kid, &dev->v_children, v_childlink)
+ vdev_delete_by_guid(kid->v_guid);
+
+ STAILQ_REMOVE(&zfs_vdevs, dev, vdev, v_alllink);
+ free(dev);
+ }
+}
+
static int
vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
vdev_t **vdevp, int is_newer)
@@ -766,6 +781,17 @@
return (spa);
}
+static void
+spa_delete_by_guid(uint64_t guid)
+{
+ spa_t *spa;
+
+ if (spa = spa_find_by_guid(guid)) {
+ STAILQ_REMOVE(&zfs_pools, spa, spa, spa_link);
+ free(spa);
+ }
+}
+
static const char *
state_name(vdev_state_t state)
{
@@ -929,7 +955,7 @@
}
static int
-vdev_probe(vdev_phys_read_t *_read, void *read_priv, spa_t **spap)
+vdev_probe_try(vdev_phys_read_t *_read, void *read_priv, spa_t **spap, int *tried_labels)
{
vdev_t vtmp;
vdev_phys_t *vdev_label = (vdev_phys_t *) zap_scratch;
@@ -950,6 +976,7 @@
int i, l, rc, is_newer;
char *upbuf;
const struct uberblock *up;
+ int best_label = 0;
/*
* Load the vdev label and figure out which
@@ -962,8 +989,10 @@
(uint64_t)sizeof (vdev_label_t));
/* Test for minimum pool size. */
- if (psize < SPA_MINDEVSIZE)
+ if (psize < SPA_MINDEVSIZE) {
+ *tried_labels = ALL_LABELS_INVALID;
return (EIO);
+ }
tmp_label = zfs_alloc(sizeof(vdev_phys_t));
@@ -990,16 +1019,21 @@
DATA_TYPE_UINT64, NULL, &pool_txg) != 0)
continue;
- if (best_txg <= pool_txg) {
+ if (best_txg <= pool_txg && (*tried_labels & (1 << l)) == 0) {
+ printf("ZFS: found label %d was written in newer txg\n", l);
best_txg = pool_txg;
+ best_label = l;
memcpy(vdev_label, tmp_label, sizeof (vdev_phys_t));
}
}
+ *tried_labels |= 1 << best_label;
zfs_free(tmp_label, sizeof (vdev_phys_t));
- if (best_txg == 0)
+ if (best_txg == 0) {
+ *tried_labels = ALL_LABELS_INVALID;
return (EIO);
+ }
if (vdev_label->vp_nvlist[0] != NV_ENCODE_XDR)
return (EIO);
@@ -1077,20 +1111,25 @@
*/
if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64,
NULL, &guid) != 0) {
- return (EIO);
+ rc = EIO;
+ goto err_delete_spa;
}
+
vdev = vdev_find(guid);
- if (vdev && vdev->v_phys_read) /* Has this vdev already been inited? */
- return (EIO);
+ if (vdev && vdev->v_phys_read) { /* Has this vdev already been inited? */
+ rc = EIO;
+ goto err_delete_spa;
+ }
if (nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST,
NULL, &vdevs)) {
- return (EIO);
+ rc = EIO;
+ goto err_delete_spa;
}
rc = vdev_init_from_nvlist(vdevs, NULL, &top_vdev, is_newer);
if (rc != 0)
- return (rc);
+ goto err_delete_vdev;
/*
* Add the toplevel vdev to the pool if its not already there.
@@ -1114,7 +1153,8 @@
vdev->v_state = VDEV_STATE_HEALTHY;
} else {
printf("ZFS: inconsistent nvlist contents\n");
- return (EIO);
+ rc = EIO;
+ goto err_delete_vdev;
}
/*
@@ -1158,10 +1198,38 @@
}
zfs_free(upbuf, VDEV_UBERBLOCK_SIZE(vdev));
- vdev->spa = spa;
- if (spap != NULL)
- *spap = spa;
- return (0);
+ /* check uberblock and return as soon as a valid dva is found */
+ for (i = 0; i < SPA_DVAS_PER_BP; i++) {
+ const dva_t *const dva = &spa->spa_uberblock.ub_rootbp.blk_dva[i];
+
+ if (dva->dva_word[0] || dva->dva_word[1]) {
+ vdev->spa = spa;
+ if (spap != NULL)
+ *spap = spa;
+ return (0);
+ }
+ }
+
+ /* no uberblock with valid dva found */
+ rc = EIO;
+err_delete_vdev:
+ vdev_delete_by_guid(guid);
+err_delete_spa:
+ spa_delete_by_guid(pool_guid);
+ return (rc);
+}
+
+static int
+vdev_probe(vdev_phys_read_t *_read, void *read_priv, spa_t **spap)
+{
+ int tried_labels = 0; // this bitmask encodes tried labels
+ int err;
+
+ do {
+ err = vdev_probe_try(_read, read_priv, spap, &tried_labels);
+ } while (err && (tried_labels != ALL_LABELS_INVALID));
+
+ return (err);
}
static int

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 15, 10:31 PM (10 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15420841
Default Alt Text
D20319.diff (4 KB)

Event Timeline