Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151176905
D51219.id158633.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
D51219.id158633.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D51219: libsa/zfs: prefer a vdev with newer txg to a stale one
Attached
Detach File
Event Timeline
Log In to Comment