usr/src/uts/common/fs/zfs/dbuf.c
changeset 2237 45affe88ed99
parent 2082 76b439ec3ac1
child 2391 2fa3fd1db808
--- a/usr/src/uts/common/fs/zfs/dbuf.c	Mon Jun 19 18:00:33 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/dbuf.c	Mon Jun 19 19:31:35 2006 -0700
@@ -712,9 +712,9 @@
 {
 	ASSERT(db->db_blkid != DB_BONUS_BLKID);
 	ASSERT(MUTEX_HELD(&db->db_mtx));
-	if (db->db_d.db_overridden_by[txg&TXG_MASK] == IN_DMU_SYNC) {
-		db->db_d.db_overridden_by[txg&TXG_MASK] = NULL;
-	} else if (db->db_d.db_overridden_by[txg&TXG_MASK] != NULL) {
+	ASSERT(db->db_d.db_overridden_by[txg&TXG_MASK] != IN_DMU_SYNC);
+
+	if (db->db_d.db_overridden_by[txg&TXG_MASK] != NULL) {
 		/* free this block */
 		ASSERT(list_link_active(&db->db_dirty_node[txg&TXG_MASK]) ||
 		    db->db_dnode->dn_free_txg == txg);
@@ -1783,6 +1783,16 @@
 	if (db->db_level == 0) {
 		data = (arc_buf_t **)&db->db_d.db_data_old[txg&TXG_MASK];
 		blksz = arc_buf_size(*data);
+
+		/*
+		 * This buffer is in the middle of an immdiate write.
+		 * Wait for the synchronous IO to complete.
+		 */
+		while (db->db_d.db_overridden_by[txg&TXG_MASK] == IN_DMU_SYNC) {
+			ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT);
+			cv_wait(&db->db_changed, &db->db_mtx);
+			ASSERT(db->db_d.db_overridden_by[txg&TXG_MASK]);
+		}
 		/*
 		 * If this buffer is currently "in use" (i.e., there are
 		 * active holds and db_data still references it), then make
@@ -2085,6 +2095,8 @@
 
 	mutex_enter(&db->db_mtx);
 
+	ASSERT(db->db_d.db_overridden_by[txg&TXG_MASK] == NULL);
+
 	if (db->db_dirtied == txg)
 		db->db_dirtied = 0;