Page MenuHomeFreeBSD

D51219.id158633.diff
No OneTemporary

D51219.id158633.diff

diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -1106,7 +1106,8 @@
}
static int
-vdev_from_nvlist(spa_t *spa, uint64_t top_guid, const nvlist_t *nvlist)
+vdev_from_nvlist(spa_t *spa, uint64_t top_guid, uint64_t txg,
+ const nvlist_t *nvlist)
{
vdev_t *top_vdev, *vdev;
nvlist_t **kids = NULL;
@@ -1120,6 +1121,7 @@
return (rc);
top_vdev->v_spa = spa;
top_vdev->v_top = top_vdev;
+ top_vdev->v_txg = txg;
vdev_insert(spa->spa_root_vdev, top_vdev);
}
@@ -1163,7 +1165,7 @@
static int
vdev_init_from_label(spa_t *spa, const nvlist_t *nvlist)
{
- uint64_t pool_guid, top_guid;
+ uint64_t pool_guid, top_guid, txg;
nvlist_t *vdevs;
int rc;
@@ -1171,13 +1173,15 @@
NULL, &pool_guid, NULL) ||
nvlist_find(nvlist, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64,
NULL, &top_guid, NULL) ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64,
+ NULL, &txg, NULL) != 0 ||
nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST,
NULL, &vdevs, NULL)) {
printf("ZFS: can't find vdev details\n");
return (ENOENT);
}
- rc = vdev_from_nvlist(spa, top_guid, vdevs);
+ rc = vdev_from_nvlist(spa, top_guid, txg, vdevs);
nvlist_destroy(vdevs);
return (rc);
}
@@ -1267,6 +1271,21 @@
return (rc);
}
+/*
+ * Shall not be called on root vdev, that is not linked into zfs_vdevs.
+ * See comment in vdev_create().
+ */
+static void
+vdev_free(struct vdev *vdev)
+{
+ struct vdev *kid, *safe;
+
+ STAILQ_FOREACH_SAFE(kid, &vdev->v_children, v_childlink, safe)
+ vdev_free(kid);
+ STAILQ_REMOVE(&zfs_vdevs, vdev, vdev, v_alllink);
+ free(vdev);
+}
+
static int
vdev_init_from_nvlist(spa_t *spa, const nvlist_t *nvlist)
{
@@ -1313,9 +1332,10 @@
vdev = vdev_find(guid);
/*
* Top level vdev is missing, create it.
+ * XXXGL: how can this happen?
*/
if (vdev == NULL)
- rc = vdev_from_nvlist(spa, guid, kids[i]);
+ rc = vdev_from_nvlist(spa, guid, 0, kids[i]);
else
rc = vdev_update_from_nvlist(guid, kids[i]);
if (rc != 0)
@@ -2006,8 +2026,7 @@
vdev_t *vdev;
nvlist_t *nvl;
uint64_t val;
- uint64_t guid;
- uint64_t pool_txg, pool_guid;
+ uint64_t guid, pool_guid, top_guid, txg;
const char *pool_name;
int rc, namelen;
@@ -2063,7 +2082,9 @@
}
if (nvlist_find(nvl, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64,
- NULL, &pool_txg, NULL) != 0 ||
+ NULL, &txg, NULL) != 0 ||
+ nvlist_find(nvl, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64,
+ NULL, &top_guid, NULL) != 0 ||
nvlist_find(nvl, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64,
NULL, &pool_guid, NULL) != 0 ||
nvlist_find(nvl, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING,
@@ -2098,9 +2119,22 @@
nvlist_destroy(nvl);
return (ENOMEM);
}
+ } else {
+ struct vdev *kid;
+
+ STAILQ_FOREACH(kid, &spa->spa_root_vdev->v_children,
+ v_childlink)
+ if (kid->v_guid == top_guid && kid->v_txg < txg) {
+ printf("ZFS: pool %s vdev %s ignoring stale "
+ "label from txg 0x%jx, using 0x%jx@0x%jx\n",
+ spa->spa_name, kid->v_name,
+ kid->v_txg, guid, txg);
+ STAILQ_REMOVE(&spa->spa_root_vdev->v_children,
+ kid, vdev, v_childlink);
+ vdev_free(kid);
+ break;
+ }
}
- if (pool_txg > spa->spa_txg)
- spa->spa_txg = pool_txg;
/*
* Get the vdev tree and create our in-core copy of it.
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -2019,6 +2019,7 @@
vdev_list_t v_children; /* children of this vdev */
const char *v_name; /* vdev name */
uint64_t v_guid; /* vdev guid */
+ uint64_t v_txg; /* most recent transaction */
uint64_t v_id; /* index in parent */
uint64_t v_psize; /* physical device capacity */
int v_ashift; /* offset to block shift */
@@ -2048,7 +2049,6 @@
STAILQ_ENTRY(spa) spa_link; /* link in global pool list */
char *spa_name; /* pool name */
uint64_t spa_guid; /* pool guid */
- uint64_t spa_txg; /* most recent transaction */
struct uberblock *spa_uberblock; /* best uberblock so far */
vdev_t *spa_root_vdev; /* toplevel vdev container */
objset_phys_t *spa_mos; /* MOS for this pool */

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 3:01 PM (9 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31038460
Default Alt Text
D51219.id158633.diff (4 KB)

Event Timeline