summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2016-11-07 15:37:12 +0200
committerRobert Mustacchi <rm@joyent.com>2017-04-05 04:23:47 +0000
commitedb35047b6b720980b6de7117a950b94ae288202 (patch)
treee0e93a8a019a41c525efec5e8bddc76fed1d52d4
parentdde8fce6139e57132d03ce57125c94e66c8ade09 (diff)
downloadillumos-joyent-edb35047b6b720980b6de7117a950b94ae288202.tar.gz
7540 loader zfs should check all labels
Reviewed by: Andriy Gapon <agapon@gmail.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com>
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/sys/boot/efi/boot1/zfs_module.c9
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efipart.c31
-rw-r--r--usr/src/boot/sys/boot/efi/loader/main.c11
-rw-r--r--usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c10
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/biosdisk.c6
-rw-r--r--usr/src/boot/sys/boot/i386/loader/main.c11
-rw-r--r--usr/src/boot/sys/boot/zfs/libzfs.h1
-rw-r--r--usr/src/boot/sys/boot/zfs/zfs.c2
-rw-r--r--usr/src/boot/sys/boot/zfs/zfsimpl.c245
10 files changed, 221 insertions, 107 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index 60ad7be601..6e85cbfb08 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)-2017.3.29.1
+BOOT_VERSION = $(LOADER_VERSION)-2017.4.1.1
diff --git a/usr/src/boot/sys/boot/efi/boot1/zfs_module.c b/usr/src/boot/sys/boot/efi/boot1/zfs_module.c
index 9cbe1582f1..c81f759876 100644
--- a/usr/src/boot/sys/boot/efi/boot1/zfs_module.c
+++ b/usr/src/boot/sys/boot/efi/boot1/zfs_module.c
@@ -38,6 +38,15 @@
static dev_info_t *devices;
+uint64_t
+ldi_get_size(void *priv)
+{
+ dev_info_t *devinfo = priv;
+
+ return (devinfo->dev->Media->BlockSize *
+ (devinfo->dev->Media->LastBlock + 1));
+}
+
static int
vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
{
diff --git a/usr/src/boot/sys/boot/efi/libefi/efipart.c b/usr/src/boot/sys/boot/efi/libefi/efipart.c
index eaaa56714b..e4f3e1151b 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efipart.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efipart.c
@@ -25,8 +25,8 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+#include <sys/disk.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stddef.h>
@@ -45,6 +45,7 @@ static int efipart_strategy(void *, int, daddr_t, size_t, char *, size_t *);
static int efipart_realstrategy(void *, int, daddr_t, size_t, char *, size_t *);
static int efipart_open(struct open_file *, ...);
static int efipart_close(struct open_file *);
+static int efipart_ioctl(struct open_file *, u_long, void *);
static int efipart_print(int);
struct devsw efipart_dev = {
@@ -54,7 +55,7 @@ struct devsw efipart_dev = {
.dv_strategy = efipart_strategy,
.dv_open = efipart_open,
.dv_close = efipart_close,
- .dv_ioctl = noioctl,
+ .dv_ioctl = efipart_ioctl,
.dv_print = efipart_print,
.dv_cleanup = NULL
};
@@ -241,6 +242,32 @@ efipart_close(struct open_file *f)
return (0);
}
+static int
+efipart_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ struct devdesc *dev;
+ EFI_BLOCK_IO *blkio;
+
+ dev = (struct devdesc *)(f->f_devdata);
+ if (dev->d_opendata == NULL)
+ return (EINVAL);
+ blkio = dev->d_opendata;
+
+ switch (cmd) {
+ case DIOCGSECTORSIZE:
+ *(u_int *)data = blkio->Media->BlockSize;
+ break;
+ case DIOCGMEDIASIZE:
+ *(uint64_t *)data = blkio->Media->BlockSize *
+ (blkio->Media->LastBlock + 1);
+ break;
+ default:
+ return (ENOTTY);
+ }
+
+ return (0);
+}
+
/*
* efipart_readwrite()
* Internal equivalent of efipart_strategy(), which operates on the
diff --git a/usr/src/boot/sys/boot/efi/loader/main.c b/usr/src/boot/sys/boot/efi/loader/main.c
index 3a056cd444..b0bbce638e 100644
--- a/usr/src/boot/sys/boot/efi/loader/main.c
+++ b/usr/src/boot/sys/boot/efi/loader/main.c
@@ -27,6 +27,7 @@
#include <sys/cdefs.h>
+#include <sys/disk.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/boot.h>
@@ -1078,4 +1079,14 @@ efi_zfs_probe(void)
(void)efi_handle_update_dev(h, &zfs_dev, unit++, guid);
}
}
+
+uint64_t
+ldi_get_size(void *priv)
+{
+ int fd = (uintptr_t) priv;
+ uint64_t size;
+
+ ioctl(fd, DIOCGMEDIASIZE, &size);
+ return (size);
+}
#endif
diff --git a/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c b/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
index 53c18c6bfe..0ee7f2c9bb 100644
--- a/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
+++ b/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
@@ -718,3 +718,13 @@ i386_zfs_probe(void)
probe_disk(devname);
}
}
+
+uint64_t
+ldi_get_size(void *priv)
+{
+ int fd = (uintptr_t) priv;
+ uint64_t size;
+
+ ioctl(fd, DIOCGMEDIASIZE, &size);
+ return (size);
+}
diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
index 3c38c44524..10efb5e422 100644
--- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
+++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c
@@ -412,8 +412,14 @@ static int
bd_ioctl(struct open_file *f, u_long cmd, void *data)
{
struct disk_devdesc *dev;
+ int rc;
dev = (struct disk_devdesc *)f->f_devdata;
+
+ rc = disk_ioctl(dev, cmd, data);
+ if (rc != ENOTTY)
+ return (rc);
+
switch (cmd) {
case DIOCGSECTORSIZE:
*(u_int *)data = BD(dev).bd_sectorsize;
diff --git a/usr/src/boot/sys/boot/i386/loader/main.c b/usr/src/boot/sys/boot/i386/loader/main.c
index 3ab2ef408f..be092c552f 100644
--- a/usr/src/boot/sys/boot/i386/loader/main.c
+++ b/usr/src/boot/sys/boot/i386/loader/main.c
@@ -37,6 +37,7 @@
#include <machine/bootinfo.h>
#include <machine/cpufunc.h>
#include <machine/psl.h>
+#include <sys/disk.h>
#include <sys/reboot.h>
#include "bootstrap.h"
@@ -436,4 +437,14 @@ i386_zfs_probe(void)
zfs_probe_dev(devname, NULL);
}
}
+
+uint64_t
+ldi_get_size(void *priv)
+{
+ int fd = (uintptr_t) priv;
+ uint64_t size;
+
+ ioctl(fd, DIOCGMEDIASIZE, &size);
+ return (size);
+}
#endif
diff --git a/usr/src/boot/sys/boot/zfs/libzfs.h b/usr/src/boot/sys/boot/zfs/libzfs.h
index b237a38b96..d08f76e569 100644
--- a/usr/src/boot/sys/boot/zfs/libzfs.h
+++ b/usr/src/boot/sys/boot/zfs/libzfs.h
@@ -63,6 +63,7 @@ char *zfs_bootfs(void *vdev);
char *zfs_fmtdev(void *vdev);
int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
int zfs_list(const char *name);
+uint64_t ldi_get_size(void *);
#ifdef __FreeBSD__
void init_zfs_bootenv(char *currdev);
int zfs_bootenv(const char *name);
diff --git a/usr/src/boot/sys/boot/zfs/zfs.c b/usr/src/boot/sys/boot/zfs/zfs.c
index 3f6455c80c..d4b7e8ef40 100644
--- a/usr/src/boot/sys/boot/zfs/zfs.c
+++ b/usr/src/boot/sys/boot/zfs/zfs.c
@@ -487,7 +487,7 @@ zfs_probe_dev(const char *devname, uint64_t *pool_guid)
{
struct ptable *table;
struct zfs_probe_args pa;
- off_t mediasz;
+ uint64_t mediasz;
int ret;
pa.fd = open(devname, O_RDONLY);
diff --git a/usr/src/boot/sys/boot/zfs/zfsimpl.c b/usr/src/boot/sys/boot/zfs/zfsimpl.c
index 87a3a34efe..c3f439855f 100644
--- a/usr/src/boot/sys/boot/zfs/zfsimpl.c
+++ b/usr/src/boot/sys/boot/zfs/zfsimpl.c
@@ -66,8 +66,7 @@ static const char *features_for_read[] = {
*/
static spa_list_t zfs_pools;
-static uint64_t zfs_crc64_table[256];
-static const dnode_phys_t *dnode_cache_obj = 0;
+static const dnode_phys_t *dnode_cache_obj;
static uint64_t dnode_cache_bn;
static char *dnode_cache_buf;
static char *zap_scratch;
@@ -519,12 +518,11 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
int nkids, i, is_new;
uint64_t is_offline, is_faulted, is_degraded, is_removed, isnt_present;
- if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID,
- DATA_TYPE_UINT64, 0, &guid)
- || nvlist_find(nvlist, ZPOOL_CONFIG_ID,
- DATA_TYPE_UINT64, 0, &id)
- || nvlist_find(nvlist, ZPOOL_CONFIG_TYPE,
- DATA_TYPE_STRING, 0, &type)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64,
+ NULL, &guid) ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_ID, DATA_TYPE_UINT64, NULL, &id) ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_TYPE, DATA_TYPE_STRING,
+ NULL, &type)) {
printf("ZFS: can't find vdev details\n");
return (ENOENT);
}
@@ -542,16 +540,16 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
is_offline = is_removed = is_faulted = is_degraded = isnt_present = 0;
- nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, 0,
- &is_offline);
- nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, 0,
- &is_removed);
- nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, 0,
- &is_faulted);
- nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, 0,
- &is_degraded);
- nvlist_find(nvlist, ZPOOL_CONFIG_NOT_PRESENT, DATA_TYPE_UINT64, 0,
- &isnt_present);
+ nvlist_find(nvlist, ZPOOL_CONFIG_OFFLINE, DATA_TYPE_UINT64, NULL,
+ &is_offline);
+ nvlist_find(nvlist, ZPOOL_CONFIG_REMOVED, DATA_TYPE_UINT64, NULL,
+ &is_removed);
+ nvlist_find(nvlist, ZPOOL_CONFIG_FAULTED, DATA_TYPE_UINT64, NULL,
+ &is_faulted);
+ nvlist_find(nvlist, ZPOOL_CONFIG_DEGRADED, DATA_TYPE_UINT64, NULL,
+ &is_degraded);
+ nvlist_find(nvlist, ZPOOL_CONFIG_NOT_PRESENT, DATA_TYPE_UINT64, NULL,
+ &isnt_present);
vdev = vdev_find(guid);
if (!vdev) {
@@ -569,30 +567,34 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
vdev->v_id = id;
vdev->v_top = pvdev != NULL ? pvdev : vdev;
if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT,
- DATA_TYPE_UINT64, 0, &ashift) == 0)
+ DATA_TYPE_UINT64, NULL, &ashift) == 0) {
vdev->v_ashift = ashift;
- else
+ } else {
vdev->v_ashift = 0;
+ }
if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY,
- DATA_TYPE_UINT64, 0, &nparity) == 0)
+ DATA_TYPE_UINT64, NULL, &nparity) == 0) {
vdev->v_nparity = nparity;
- else
+ } else {
vdev->v_nparity = 0;
+ }
if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH,
- DATA_TYPE_STRING, 0, &path) == 0) {
+ DATA_TYPE_STRING, NULL, &path) == 0) {
if (strncmp(path, "/dev/dsk/", 9) == 0)
path += 9;
vdev->v_name = strdup(path);
if (nvlist_find(nvlist, ZPOOL_CONFIG_PHYS_PATH,
- DATA_TYPE_STRING, 0, &path) == 0)
+ DATA_TYPE_STRING, NULL, &path) == 0) {
vdev->v_phys_path = strdup(path);
- else
+ } else {
vdev->v_phys_path = NULL;
+ }
if (nvlist_find(nvlist, ZPOOL_CONFIG_DEVID,
- DATA_TYPE_STRING, 0, &path) == 0)
+ DATA_TYPE_STRING, NULL, &path) == 0) {
vdev->v_devid = strdup(path);
- else
+ } else {
vdev->v_devid = NULL;
+ }
} else {
if (!strcmp(type, "raidz")) {
if (vdev->v_nparity == 1)
@@ -631,8 +633,8 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t *pvdev,
vdev->v_state = VDEV_STATE_CANT_OPEN;
}
- rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN,
- DATA_TYPE_NVLIST_ARRAY, &nkids, &kids);
+ rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY,
+ &nkids, &kids);
/*
* Its ok if we don't have any kids.
*/
@@ -747,12 +749,17 @@ spa_get_primary_vdev(const spa_t *spa)
}
static spa_t *
-spa_create(uint64_t guid)
+spa_create(uint64_t guid, const char *name)
{
spa_t *spa;
- spa = malloc(sizeof(spa_t));
+ if ((spa = malloc(sizeof(spa_t))) == NULL)
+ return (NULL);
memset(spa, 0, sizeof(spa_t));
+ if ((spa->spa_name = strdup(name)) == NULL) {
+ free(spa);
+ return (NULL);
+ }
STAILQ_INIT(&spa->spa_vdevs);
spa->spa_guid = guid;
STAILQ_INSERT_TAIL(&zfs_pools, spa, spa_link);
@@ -899,24 +906,39 @@ spa_all_status(void)
return (ret);
}
+uint64_t
+vdev_label_offset(uint64_t psize, int l, uint64_t offset)
+{
+ uint64_t label_offset;
+
+ if (l < VDEV_LABELS / 2)
+ label_offset = 0;
+ else
+ label_offset = psize - VDEV_LABELS * sizeof (vdev_label_t);
+
+ return (offset + l * sizeof (vdev_label_t) + label_offset);
+}
+
static int
vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
{
vdev_t vtmp;
vdev_phys_t *vdev_label = (vdev_phys_t *) zap_scratch;
+ vdev_phys_t *tmp_label = zfs_alloc(sizeof(vdev_phys_t));
spa_t *spa;
vdev_t *vdev, *top_vdev, *pool_vdev;
off_t off;
blkptr_t bp;
- const unsigned char *nvlist;
+ const unsigned char *nvlist = NULL;
uint64_t val;
uint64_t guid;
+ uint64_t best_txg = 0;
uint64_t pool_txg, pool_guid;
- uint64_t is_log;
+ uint64_t psize;
const char *pool_name;
const unsigned char *vdevs;
const unsigned char *features;
- int i, rc, is_newer;
+ int i, l, rc, is_newer;
char *upbuf;
const struct uberblock *up;
@@ -927,26 +949,47 @@ 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;
- off = offsetof(vdev_label_t, vl_vdev_phys);
- BP_ZERO(&bp);
- BP_SET_LSIZE(&bp, sizeof(vdev_phys_t));
- BP_SET_PSIZE(&bp, sizeof(vdev_phys_t));
- BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
- BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
- DVA_SET_OFFSET(BP_IDENTITY(&bp), off);
- ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
- if (vdev_read_phys(&vtmp, &bp, vdev_label, off, 0))
- return (EIO);
+ psize = P2ALIGN(ldi_get_size(read_priv),
+ (uint64_t)sizeof (vdev_label_t));
- if (vdev_label->vp_nvlist[0] != NV_ENCODE_XDR) {
- return (EIO);
+ for (l = 0; l < VDEV_LABELS; l++) {
+ off = vdev_label_offset(psize, l,
+ offsetof(vdev_label_t, vl_vdev_phys));
+
+ BP_ZERO(&bp);
+ BP_SET_LSIZE(&bp, sizeof(vdev_phys_t));
+ BP_SET_PSIZE(&bp, sizeof(vdev_phys_t));
+ BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
+ BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
+ DVA_SET_OFFSET(BP_IDENTITY(&bp), off);
+ ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
+
+ if (vdev_read_phys(&vtmp, &bp, tmp_label, off, 0))
+ continue;
+
+ if (tmp_label->vp_nvlist[0] != NV_ENCODE_XDR)
+ continue;
+
+ nvlist = (const unsigned char *) tmp_label->vp_nvlist + 4;
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_TXG,
+ DATA_TYPE_UINT64, NULL, &pool_txg) != 0)
+ continue;
+
+ if (best_txg <= pool_txg) {
+ best_txg = pool_txg;
+ memcpy(vdev_label, tmp_label, sizeof (vdev_phys_t));
+ }
}
+ zfs_free(tmp_label, sizeof (vdev_phys_t));
+
+ if (vdev_label->vp_nvlist[0] != NV_ENCODE_XDR)
+ return (EIO);
+
nvlist = (const unsigned char *) vdev_label->vp_nvlist + 4;
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_VERSION,
- DATA_TYPE_UINT64, 0, &val)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_VERSION, DATA_TYPE_UINT64,
+ NULL, &val) != 0) {
return (EIO);
}
@@ -957,15 +1000,14 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
}
/* Check ZFS features for read */
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_FEATURES_FOR_READ,
- DATA_TYPE_NVLIST, 0, &features) == 0
- && nvlist_check_features_for_read(features) != 0)
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_FEATURES_FOR_READ,
+ DATA_TYPE_NVLIST, NULL, &features) == 0 &&
+ nvlist_check_features_for_read(features) != 0) {
return (EIO);
+ }
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_POOL_STATE,
- DATA_TYPE_UINT64, 0, &val)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_STATE, DATA_TYPE_UINT64,
+ NULL, &val) != 0) {
return (EIO);
}
@@ -974,15 +1016,12 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
return (EIO);
}
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_POOL_TXG,
- DATA_TYPE_UINT64, 0, &pool_txg)
- || nvlist_find(nvlist,
- ZPOOL_CONFIG_POOL_GUID,
- DATA_TYPE_UINT64, 0, &pool_guid)
- || nvlist_find(nvlist,
- ZPOOL_CONFIG_POOL_NAME,
- DATA_TYPE_STRING, 0, &pool_name)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_TXG, DATA_TYPE_UINT64,
+ NULL, &pool_txg) != 0 ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_POOL_GUID, DATA_TYPE_UINT64,
+ NULL, &pool_guid) != 0 ||
+ nvlist_find(nvlist, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING,
+ NULL, &pool_name) != 0) {
/*
* Cache and spare devices end up here - just ignore
* them.
@@ -991,25 +1030,26 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
return (EIO);
}
- is_log = 0;
- (void) nvlist_find(nvlist, ZPOOL_CONFIG_IS_LOG, DATA_TYPE_UINT64, 0,
- &is_log);
- if (is_log)
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_IS_LOG, DATA_TYPE_UINT64,
+ NULL, &val) == 0 && val != 0) {
return (EIO);
+ }
/*
* Create the pool if this is the first time we've seen it.
*/
spa = spa_find_by_guid(pool_guid);
- if (!spa) {
- spa = spa_create(pool_guid);
- spa->spa_name = strdup(pool_name);
+ if (spa == NULL) {
+ spa = spa_create(pool_guid, pool_name);
+ if (spa == NULL)
+ return (ENOMEM);
}
if (pool_txg > spa->spa_txg) {
spa->spa_txg = pool_txg;
is_newer = 1;
- } else
+ } else {
is_newer = 0;
+ }
/*
* Get the vdev tree and create our in-core copy of it.
@@ -1017,23 +1057,21 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
* be some kind of alias (overlapping slices, dangerously dedicated
* disks etc).
*/
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_GUID,
- DATA_TYPE_UINT64, 0, &guid)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64,
+ NULL, &guid) != 0) {
return (EIO);
}
vdev = vdev_find(guid);
if (vdev && vdev->v_phys_read) /* Has this vdev already been inited? */
return (EIO);
- if (nvlist_find(nvlist,
- ZPOOL_CONFIG_VDEV_TREE,
- DATA_TYPE_NVLIST, 0, &vdevs)) {
+ if (nvlist_find(nvlist, ZPOOL_CONFIG_VDEV_TREE, DATA_TYPE_NVLIST,
+ NULL, &vdevs)) {
return (EIO);
}
rc = vdev_init_from_nvlist(vdevs, NULL, &top_vdev, is_newer);
- if (rc)
+ if (rc != 0)
return (rc);
/*
@@ -1071,35 +1109,36 @@ vdev_probe(vdev_phys_read_t *phys_read, void *read_priv, spa_t **spap)
*/
upbuf = zfs_alloc(VDEV_UBERBLOCK_SIZE(vdev));
up = (const struct uberblock *)upbuf;
- for (i = 0;
- i < VDEV_UBERBLOCK_COUNT(vdev);
- i++) {
- off = VDEV_UBERBLOCK_OFFSET(vdev, i);
- BP_ZERO(&bp);
- DVA_SET_OFFSET(&bp.blk_dva[0], off);
- BP_SET_LSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
- BP_SET_PSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
- BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
- BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
- ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
-
- if (vdev_read_phys(vdev, &bp, upbuf, off, 0))
- continue;
+ for (l = 0; l < VDEV_LABELS; l++) {
+ for (i = 0; i < VDEV_UBERBLOCK_COUNT(vdev); i++) {
+ off = vdev_label_offset(psize, l,
+ VDEV_UBERBLOCK_OFFSET(vdev, i));
+ BP_ZERO(&bp);
+ DVA_SET_OFFSET(&bp.blk_dva[0], off);
+ BP_SET_LSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
+ BP_SET_PSIZE(&bp, VDEV_UBERBLOCK_SIZE(vdev));
+ BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
+ BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
+ ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0);
+
+ if (vdev_read_phys(vdev, &bp, upbuf, off, 0) != 0)
+ continue;
- if (up->ub_magic != UBERBLOCK_MAGIC)
- continue;
- if (up->ub_txg < spa->spa_txg)
- continue;
- if (up->ub_txg > spa->spa_uberblock.ub_txg) {
- spa->spa_uberblock = *up;
- } else if (up->ub_txg == spa->spa_uberblock.ub_txg) {
- if (up->ub_timestamp > spa->spa_uberblock.ub_timestamp)
+ if (up->ub_magic != UBERBLOCK_MAGIC)
+ continue;
+ if (up->ub_txg < spa->spa_txg)
+ continue;
+ if (up->ub_txg > spa->spa_uberblock.ub_txg ||
+ (up->ub_txg == spa->spa_uberblock.ub_txg &&
+ up->ub_timestamp >
+ spa->spa_uberblock.ub_timestamp)) {
spa->spa_uberblock = *up;
+ }
}
}
zfs_free(upbuf, VDEV_UBERBLOCK_SIZE(vdev));
- if (spap)
+ if (spap != NULL)
*spap = spa;
return (0);
}