summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2019-10-29 13:33:34 +0200
committerToomas Soome <tsoome@me.com>2019-11-04 22:55:54 +0200
commit4c2b14fdad703c6c165e45413b79543a54e88edb (patch)
tree84cdab5b6b7bdcd4f724e642a2f305cb960946a1
parent5e8da2b9e1f3fba257c0c163a81a375107b9ee64 (diff)
downloadillumos-joyent-4c2b14fdad703c6c165e45413b79543a54e88edb.tar.gz
11888 loader: calculate physical vdev psize from asize
Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/lib/libstand/zfs/zfsimpl.c29
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h3
3 files changed, 26 insertions, 8 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index 30e5014dea..cf66bc1bc8 100644
--- a/usr/src/boot/Makefile.version
+++ b/usr/src/boot/Makefile.version
@@ -33,4 +33,4 @@ LOADER_VERSION = 1.1
# Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes.
# The version is processed from left to right, the version number can only
# be increased.
-BOOT_VERSION = $(LOADER_VERSION)-2019.10.26.1
+BOOT_VERSION = $(LOADER_VERSION)-2019.10.29.1
diff --git a/usr/src/boot/lib/libstand/zfs/zfsimpl.c b/usr/src/boot/lib/libstand/zfs/zfsimpl.c
index 9958d5ea4b..e595273c9b 100644
--- a/usr/src/boot/lib/libstand/zfs/zfsimpl.c
+++ b/usr/src/boot/lib/libstand/zfs/zfsimpl.c
@@ -1099,7 +1099,7 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
vdev_t **vdevp, int is_newer)
{
int rc;
- uint64_t guid, id, ashift, nparity;
+ uint64_t guid, id, ashift, asize, nparity;
const char *type;
const char *path;
vdev_t *vdev, *kid;
@@ -1178,6 +1178,11 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
} else {
vdev->v_ashift = 0;
}
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_ASIZE,
+ DATA_TYPE_UINT64, NULL, &asize) == 0) {
+ vdev->v_psize = asize +
+ VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+ }
if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
DATA_TYPE_UINT64, NULL, &nparity) == 0) {
vdev->v_nparity = nparity;
@@ -1543,7 +1548,6 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
uint64_t guid;
uint64_t best_txg = 0;
uint64_t pool_txg, pool_guid;
- uint64_t psize;
const char *pool_name;
const unsigned char *vdevs;
const unsigned char *features;
@@ -1558,17 +1562,17 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
memset(&vtmp, 0, sizeof(vtmp));
vtmp.v_phys_read = phys_read;
vtmp.v_read_priv = read_priv;
- psize = P2ALIGN(ldi_get_size(read_priv),
+ vtmp.v_psize = P2ALIGN(ldi_get_size(read_priv),
(uint64_t)sizeof (vdev_label_t));
/* Test for minimum device size. */
- if (psize < SPA_MINDEVSIZE)
+ if (vtmp.v_psize < SPA_MINDEVSIZE)
return (EIO);
tmp_label = zfs_alloc(sizeof (vdev_phys_t));
for (l = 0; l < VDEV_LABELS; l++) {
- off = vdev_label_offset(psize, l,
+ off = vdev_label_offset(vtmp.v_psize, l,
offsetof(vdev_label_t, vl_vdev_phys));
BP_ZERO(&bp);
@@ -1591,8 +1595,20 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
continue;
if (best_txg <= pool_txg) {
+ uint64_t asize;
+
best_txg = pool_txg;
memcpy(vdev_label, tmp_label, sizeof (vdev_phys_t));
+
+ /*
+ * Use asize from pool config. We need this
+ * because we can get bad value from BIOS.
+ */
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_ASIZE,
+ DATA_TYPE_UINT64, NULL, &asize) == 0) {
+ vtmp.v_psize = asize +
+ VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+ }
}
}
@@ -1712,6 +1728,7 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
vdev->v_phys_read = phys_read;
vdev->v_read_priv = read_priv;
vdev->v_state = VDEV_STATE_HEALTHY;
+ vdev->v_psize = vtmp.v_psize;
} else {
printf("ZFS: inconsistent nvlist contents\n");
return (EIO);
@@ -1735,7 +1752,7 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
up = (const struct uberblock *)upbuf;
for (l = 0; l < VDEV_LABELS; l++) {
for (i = 0; i < VDEV_UBERBLOCK_COUNT(vdev); i++) {
- off = vdev_label_offset(psize, l,
+ off = vdev_label_offset(vdev->v_psize, l,
VDEV_UBERBLOCK_OFFSET(vdev, i));
BP_ZERO(&bp);
DVA_SET_OFFSET(&bp.blk_dva[0], off);
diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
index 459324b88a..2a71fcb067 100644
--- a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
+++ b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
@@ -1671,7 +1671,8 @@ typedef struct vdev {
const char *v_phys_path; /* vdev bootpath */
const char *v_devid; /* vdev devid */
uint64_t v_guid; /* vdev guid */
- int v_id; /* index in parent */
+ uint64_t v_id; /* index in parent */
+ uint64_t v_psize; /* physical device capacity */
int v_ashift; /* offset to block shift */
int v_nparity; /* # parity for raidz */
struct vdev *v_top; /* parent vdev */