summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2012-10-06 19:40:12 +0000
committeravg <avg@FreeBSD.org>2012-10-06 19:40:12 +0000
commit0eb55a335e02684f5b62f0211868d34211e09906 (patch)
tree8a5577f4ba8ba083258f247a3e5694364645092b
parent532bfc1c2114a1d6524a088b725c531d959dd2f0 (diff)
downloadFreeBSD-src-0eb55a335e02684f5b62f0211868d34211e09906.zip
FreeBSD-src-0eb55a335e02684f5b62f0211868d34211e09906.tar.gz
boot/zfs: call zfs_spa_init for all found pools
... and drop those for which it fails. Also, add more sanity checking to the function. MFC after: 16 days
-rw-r--r--sys/boot/zfs/zfs.c31
-rw-r--r--sys/boot/zfs/zfsimpl.c7
2 files changed, 22 insertions, 16 deletions
diff --git a/sys/boot/zfs/zfs.c b/sys/boot/zfs/zfs.c
index 3fc5f50..afb4b70 100644
--- a/sys/boot/zfs/zfs.c
+++ b/sys/boot/zfs/zfs.c
@@ -370,10 +370,28 @@ vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size)
static int
zfs_dev_init(void)
{
+ spa_t *spa;
+ spa_t *next;
+ spa_t *prev;
+
zfs_init();
if (archsw.arch_zfs_probe == NULL)
return (ENXIO);
archsw.arch_zfs_probe();
+
+ prev = NULL;
+ spa = STAILQ_FIRST(&zfs_pools);
+ while (spa != NULL) {
+ next = STAILQ_NEXT(spa, spa_link);
+ if (zfs_spa_init(spa)) {
+ if (prev == NULL)
+ STAILQ_REMOVE_HEAD(&zfs_pools, spa_link);
+ else
+ STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link);
+ } else
+ prev = spa;
+ spa = next;
+ }
return (0);
}
@@ -519,9 +537,6 @@ zfs_dev_open(struct open_file *f, ...)
spa = spa_find_by_guid(dev->pool_guid);
if (!spa)
return (ENXIO);
- rv = zfs_spa_init(spa);
- if (rv != 0)
- return (rv);
mount = malloc(sizeof(*mount));
rv = zfs_mount(spa, dev->root_guid, mount);
if (rv != 0) {
@@ -601,9 +616,6 @@ zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
spa = spa_find_by_name(poolname);
if (!spa)
return (ENXIO);
- rv = zfs_spa_init(spa);
- if (rv != 0)
- return (rv);
dev->pool_guid = spa->spa_guid;
if (rootname[0] != '\0') {
rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
@@ -638,10 +650,6 @@ zfs_fmtdev(void *vdev)
printf("ZFS: can't find pool by guid\n");
return (buf);
}
- if (zfs_spa_init(spa) != 0) {
- printf("ZFS: can't init pool\n");
- return (buf);
- }
if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
printf("ZFS: can't find root filesystem\n");
return (buf);
@@ -681,9 +689,6 @@ zfs_list(const char *name)
spa = spa_find_by_name(poolname);
if (!spa)
return (ENXIO);
- rv = zfs_spa_init(spa);
- if (rv != 0)
- return (rv);
if (dsname != NULL)
rv = zfs_lookup_dataset(spa, dsname, &objid);
else
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index 3ce57f8..58e5631 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -1881,13 +1881,14 @@ static int
zfs_spa_init(spa_t *spa)
{
- if (spa->spa_inited)
- return (0);
if (zio_read(spa, &spa->spa_uberblock.ub_rootbp, &spa->spa_mos)) {
printf("ZFS: can't read MOS of pool %s\n", spa->spa_name);
return (EIO);
}
- spa->spa_inited = 1;
+ if (spa->spa_mos.os_type != DMU_OST_META) {
+ printf("ZFS: corrupted MOS of pool %s\n", spa->spa_name);
+ return (EIO);
+ }
return (0);
}
OpenPOWER on IntegriCloud