6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD
authorck153898
Fri, 30 Nov 2007 13:22:52 -0800
changeset 5569 d3caac36d311
parent 5568 ac217d9f8190
child 5570 aa78af6a42b2
6634062 dsl_dataset_open_obj misuses RW_LOCK_HELD 6634881 dsl_prop_register can release a lock it doesn't own
usr/src/uts/common/fs/zfs/dsl_dataset.c
usr/src/uts/common/fs/zfs/dsl_prop.c
--- 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);
 	}