Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105324123
D20319.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D20319.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D20319: stand/zfs: don't fail boot if the first label is broken
Attached
Detach File
Event Timeline
Log In to Comment