summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2010-05-21 08:50:34 +0000
committermm <mm@FreeBSD.org>2010-05-21 08:50:34 +0000
commitc47ee5a2cae1d2e03f929710d8ef0ac7e14b81c6 (patch)
treea34e509dfe56e35e652a6c50d7609d506d145139 /sys/cddl
parent2f9e8c891f2eab56fd40a8048a31901ebfa0c2e7 (diff)
downloadFreeBSD-src-c47ee5a2cae1d2e03f929710d8ef0ac7e14b81c6.zip
FreeBSD-src-c47ee5a2cae1d2e03f929710d8ef0ac7e14b81c6.tar.gz
Fix: vdev_reopen() can lead to failed allocations
OpenSolaris onnv-revision: 7980:589f37f25048 Approved by: pjd, delphij (mentor) Obtained from: OpenSolaris (Bug ID 6764914) MFC after: 3 days
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h1
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c13
3 files changed, 15 insertions, 1 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
index 22b56d6..47f8f5f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c
@@ -781,7 +781,7 @@ top:
/*
* Don't allocate from faulted devices.
*/
- if (!vdev_writeable(vd))
+ if (!vdev_allocatable(vd))
goto next;
/*
* Avoid writing single-copy data to a failing vdev
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
index 0133895..c070d6f 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
@@ -85,6 +85,7 @@ extern void vdev_clear(spa_t *spa, vdev_t *vd);
extern boolean_t vdev_is_dead(vdev_t *vd);
extern boolean_t vdev_readable(vdev_t *vd);
extern boolean_t vdev_writeable(vdev_t *vd);
+extern boolean_t vdev_allocatable(vdev_t *vd);
extern boolean_t vdev_accessible(vdev_t *vd, zio_t *zio);
extern void vdev_cache_init(vdev_t *vd);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
index ee818e5..daab409 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
@@ -1861,6 +1861,19 @@ vdev_writeable(vdev_t *vd)
}
boolean_t
+vdev_allocatable(vdev_t *vd)
+{
+ /*
+ * We currently allow allocations from vdevs which maybe in the
+ * process of reopening (i.e. VDEV_STATE_CLOSED). If the device
+ * fails to reopen then we'll catch it later when we're holding
+ * the proper locks.
+ */
+ return (!(vdev_is_dead(vd) && vd->vdev_state != VDEV_STATE_CLOSED) &&
+ !vd->vdev_cant_write);
+}
+
+boolean_t
vdev_accessible(vdev_t *vd, zio_t *zio)
{
ASSERT(zio->io_vd == vd);
OpenPOWER on IntegriCloud