6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
6634881 dsl_prop_register can release a lock it doesn't own
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Fri Nov 30 13:11:57 2007 -0800
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Fri Nov 30 13:22:52 2007 -0800
@@ -375,8 +375,14 @@
}
if (!dsl_dataset_is_snapshot(ds)) {
+ /*
+ * In sync context, we're called with either no lock
+ * or with the write lock. If we're not syncing,
+ * we're always called with the read lock held.
+ */
boolean_t need_lock =
- !RW_LOCK_HELD(&dp->dp_config_rwlock);
+ !RW_WRITE_HELD(&dp->dp_config_rwlock) &&
+ dsl_pool_sync_context(dp);
if (need_lock)
rw_enter(&dp->dp_config_rwlock, RW_READER);
--- a/usr/src/uts/common/fs/zfs/dsl_prop.c Fri Nov 30 13:11:57 2007 -0800
+++ b/usr/src/uts/common/fs/zfs/dsl_prop.c Fri Nov 30 13:22:52 2007 -0800
@@ -130,7 +130,8 @@
err = dsl_prop_get_impl(dd, propname, 8, 1, &value, NULL);
if (err != 0) {
- rw_exit(&dd->dd_pool->dp_config_rwlock);
+ if (need_rwlock)
+ rw_exit(&dd->dd_pool->dp_config_rwlock);
return (err);
}