summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2013-04-06 08:02:10 +0000
committermm <mm@FreeBSD.org>2013-04-06 08:02:10 +0000
commit9dc1b0c34c49a9a900c03d07b6cd7f37a750ab34 (patch)
tree65f45afeee20bf66e69bb8aadf693ad8edd9caec
parent90b36f897687e2b5fdcf1523511f1ee23580c728 (diff)
downloadFreeBSD-src-9dc1b0c34c49a9a900c03d07b6cd7f37a750ab34.zip
FreeBSD-src-9dc1b0c34c49a9a900c03d07b6cd7f37a750ab34.tar.gz
Update vendor-sys/illumos/dist to illumos-gate 13992:313c3db67359
Illumos ZFS issues: 3639 zpool.cache should skip over readonly pools 3640 want automatic devid updates
-rw-r--r--uts/common/fs/zfs/spa_config.c10
-rw-r--r--uts/common/fs/zfs/vdev_disk.c28
2 files changed, 35 insertions, 3 deletions
diff --git a/uts/common/fs/zfs/spa_config.c b/uts/common/fs/zfs/spa_config.c
index 3665450..b113ce9 100644
--- a/uts/common/fs/zfs/spa_config.c
+++ b/uts/common/fs/zfs/spa_config.c
@@ -222,7 +222,15 @@ spa_config_sync(spa_t *target, boolean_t removing, boolean_t postsysevent)
*/
nvl = NULL;
while ((spa = spa_next(spa)) != NULL) {
- if (spa == target && removing)
+ /*
+ * Skip over our own pool if we're about to remove
+ * ourselves from the spa namespace or any pool that
+ * is readonly. Since we cannot guarantee that a
+ * readonly pool would successfully import upon reboot,
+ * we don't allow them to be written to the cache file.
+ */
+ if ((spa == target && removing) ||
+ !spa_writeable(spa))
continue;
mutex_enter(&spa->spa_props_lock);
diff --git a/uts/common/fs/zfs/vdev_disk.c b/uts/common/fs/zfs/vdev_disk.c
index aa5b67d..c526363 100644
--- a/uts/common/fs/zfs/vdev_disk.c
+++ b/uts/common/fs/zfs/vdev_disk.c
@@ -139,6 +139,8 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
int error;
dev_t dev;
int otyp;
+ boolean_t validate_devid = B_FALSE;
+ ddi_devid_t devid;
/*
* We must have a pathname, and it must be absolute.
@@ -187,7 +189,6 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
error = EINVAL; /* presume failure */
if (vd->vdev_path != NULL) {
- ddi_devid_t devid;
if (vd->vdev_wholedisk == -1ULL) {
size_t len = strlen(vd->vdev_path) + 3;
@@ -236,9 +237,10 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
* If we were unable to open by path, or the devid check fails, open by
* devid instead.
*/
- if (error != 0 && vd->vdev_devid != NULL)
+ if (error != 0 && vd->vdev_devid != NULL) {
error = ldi_open_by_devid(dvd->vd_devid, dvd->vd_minor,
spa_mode(spa), kcred, &dvd->vd_lh, zfs_li);
+ }
/*
* If all else fails, then try opening by physical path (if available)
@@ -247,6 +249,9 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
* level vdev validation will prevent us from opening the wrong device.
*/
if (error) {
+ if (vd->vdev_devid != NULL)
+ validate_devid = B_TRUE;
+
if (vd->vdev_physpath != NULL &&
(dev = ddi_pathname_to_dev_t(vd->vdev_physpath)) != NODEV)
error = ldi_open_by_dev(&dev, OTYP_BLK, spa_mode(spa),
@@ -268,6 +273,25 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
}
/*
+ * Now that the device has been successfully opened, update the devid
+ * if necessary.
+ */
+ if (validate_devid && spa_writeable(spa) &&
+ ldi_get_devid(dvd->vd_lh, &devid) == 0) {
+ if (ddi_devid_compare(devid, dvd->vd_devid) != 0) {
+ char *vd_devid;
+
+ vd_devid = ddi_devid_str_encode(devid, dvd->vd_minor);
+ zfs_dbgmsg("vdev %s: update devid from %s, "
+ "to %s", vd->vdev_path, vd->vdev_devid, vd_devid);
+ spa_strfree(vd->vdev_devid);
+ vd->vdev_devid = spa_strdup(vd_devid);
+ ddi_devid_str_free(vd_devid);
+ }
+ ddi_devid_free(devid);
+ }
+
+ /*
* Once a device is opened, verify that the physical device path (if
* available) is up to date.
*/
OpenPOWER on IntegriCloud