Page MenuHomeFreeBSD

D4986.id12436.diff
No OneTemporary

D4986.id12436.diff

Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
@@ -367,6 +367,7 @@
*/
/* zdb uses this tunable, so it must be declared here to make lint happy. */
extern int zfs_vdev_cache_size;
+extern uint_t zfs_geom_probe_vdev_key;
#ifdef illumos
/*
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -61,6 +61,13 @@
SYSCTL_INT(_vfs_zfs_vdev, OID_AUTO, bio_delete_disable, CTLFLAG_RWTUN,
&vdev_geom_bio_delete_disable, 0, "Disable BIO_DELETE");
+/*
+ * Thread local storage used to indicate when a thread is probing geoms
+ * for their guids. If NULL, this thread is not tasting geoms. If non NULL,
+ * it is looking for a replacement for the vdev_t* that is its value.
+ */
+uint_t zfs_geom_probe_vdev_key;
+
static void
vdev_geom_set_rotation_rate(vdev_t *vd, struct g_consumer *cp)
{
@@ -326,9 +333,8 @@
static void
vdev_geom_taste_orphan(struct g_consumer *cp)
{
-
- KASSERT(1 == 0, ("%s called while tasting %s.", __func__,
- cp->provider->name));
+ ZFS_LOG(0, "WARNING: Orphan %s while tasting its VDev GUID.",
+ cp->provider->name);
}
static int
@@ -575,7 +581,6 @@
g_topology_assert();
zgp = g_new_geomf(&zfs_vdev_class, "zfs::vdev::taste");
- /* This orphan function should be never called. */
zgp->orphan = vdev_geom_taste_orphan;
zcp = g_new_consumer(zgp);
@@ -702,6 +707,9 @@
size_t bufsize;
int error;
+ /* Set the TLS to indicate downstack that we should not access zvols*/
+ VERIFY(tsd_set(zfs_geom_probe_vdev_key, vd) == 0);
+
/*
* We must have a pathname, and it must be absolute.
*/
@@ -751,6 +759,9 @@
}
}
+ /* Clear the TLS now that tasting is done */
+ VERIFY(tsd_set(zfs_geom_probe_vdev_key, NULL) == 0);
+
if (cp == NULL) {
ZFS_LOG(1, "Provider %s not found.", vd->vdev_path);
error = ENOENT;
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -206,6 +206,7 @@
uint_t zfs_fsyncer_key;
extern uint_t rrw_tsd_key;
static uint_t zfs_allow_log_key;
+extern uint_t zfs_geom_probe_vdev_key;
typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
@@ -6602,6 +6603,7 @@
tsd_create(&zfs_fsyncer_key, NULL);
tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
+ tsd_create(&zfs_geom_probe_vdev_key, NULL);
printf("ZFS storage pool version: features support (" SPA_VERSION_STRING ")\n");
root_mount_rel(zfs_root_token);
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -1114,36 +1114,30 @@
return (err);
}
#else /* !illumos */
- boolean_t locked = B_FALSE;
-
- /*
- * Protect against recursively entering spa_namespace_lock
- * when spa_open() is used for a pool on a (local) ZVOL(s).
- * This is needed since we replaced upstream zfsdev_state_lock
- * with spa_namespace_lock in the ZVOL code.
- * We are using the same trick as spa_open().
- * Note that calls in zvol_first_open which need to resolve
- * pool name to a spa object will enter spa_open()
- * recursively, but that function already has all the
- * necessary protection.
- */
- if (!MUTEX_HELD(&zfsdev_state_lock)) {
- mutex_enter(&zfsdev_state_lock);
- locked = B_TRUE;
+ if (tsd_get(zfs_geom_probe_vdev_key) != NULL) {
+ /*
+ * if zfs_geom_probe_vdev_key is set, that means that zfs is
+ * attempting to probe geom providers while looking for a
+ * replacement for a missing VDEV. In this case, the
+ * spa_namespace_lock will not be held, but it is still illegal
+ * to use a zvol as a vdev. Deadlocks can result if another
+ * thread has spa_namespace_lock
+ */
+ return (EOPNOTSUPP);
}
+ mutex_enter(&zfsdev_state_lock);
+
zv = pp->private;
if (zv == NULL) {
- if (locked)
- mutex_exit(&zfsdev_state_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
if (zv->zv_total_opens == 0) {
err = zvol_first_open(zv);
if (err) {
- if (locked)
- mutex_exit(&zfsdev_state_lock);
+ mutex_exit(&zfsdev_state_lock);
return (err);
}
pp->mediasize = zv->zv_volsize;
@@ -1177,8 +1171,7 @@
mutex_exit(&zfsdev_state_lock);
#else
zv->zv_total_opens += count;
- if (locked)
- mutex_exit(&zfsdev_state_lock);
+ mutex_exit(&zfsdev_state_lock);
#endif
return (err);
@@ -1188,8 +1181,7 @@
#ifdef illumos
mutex_exit(&zfsdev_state_lock);
#else
- if (locked)
- mutex_exit(&zfsdev_state_lock);
+ mutex_exit(&zfsdev_state_lock);
#endif
return (err);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 28, 5:17 PM (1 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37470994
Default Alt Text
D4986.id12436.diff (5 KB)

Event Timeline