6523336 panic dr->dt.dl.dr_override_state == DR_NOT_OVERRIDDEN, file: ../../ common/fs/zfs/dbuf.c line: 2195
6549634 dn_dbfs_mtx should be held when calling list_link_active() in dbuf_destroy()
--- a/usr/src/uts/common/fs/zfs/dbuf.c Thu May 24 12:17:11 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dbuf.c Thu May 24 12:18:14 2007 -0700
@@ -1471,17 +1471,23 @@
if (db->db_blkid != DB_BONUS_BLKID) {
dnode_t *dn = db->db_dnode;
+ boolean_t need_mutex = !MUTEX_HELD(&dn->dn_dbufs_mtx);
+
+ if (need_mutex)
+ mutex_enter(&dn->dn_dbufs_mtx);
/*
* If this dbuf is still on the dn_dbufs list,
* remove it from that list.
*/
if (list_link_active(&db->db_link)) {
- mutex_enter(&dn->dn_dbufs_mtx);
+ ASSERT(need_mutex);
list_remove(&dn->dn_dbufs, db);
mutex_exit(&dn->dn_dbufs_mtx);
dnode_rele(dn, db);
+ } else if (need_mutex) {
+ mutex_exit(&dn->dn_dbufs_mtx);
}
dbuf_hash_remove(db);
}
@@ -1489,6 +1495,7 @@
db->db_dnode = NULL;
db->db_buf = NULL;
+ ASSERT(!list_link_active(&db->db_link));
ASSERT(db->db.db_data == NULL);
ASSERT(db->db_hash_next == NULL);
ASSERT(db->db_blkptr == NULL);
@@ -1939,6 +1946,14 @@
}
/*
+ * This function may have dropped the db_mtx lock allowing a dmu_sync
+ * operation to sneak in. As a result, we need to ensure that we
+ * don't check the dr_override_state until we have returned from
+ * dbuf_check_blkptr.
+ */
+ dbuf_check_blkptr(dn, db);
+
+ /*
* If this buffer is in the middle of an immdiate write,
* wait for the synchronous IO to complete.
*/
@@ -1948,8 +1963,6 @@
ASSERT(dr->dt.dl.dr_override_state != DR_NOT_OVERRIDDEN);
}
- dbuf_check_blkptr(dn, db);
-
/*
* If this dbuf has already been written out via an immediate write,
* just complete the write by copying over the new block pointer and
--- a/usr/src/uts/common/fs/zfs/dnode_sync.c Thu May 24 12:17:11 2007 -0700
+++ b/usr/src/uts/common/fs/zfs/dnode_sync.c Thu May 24 12:18:14 2007 -0700
@@ -55,9 +55,8 @@
ASSERT(db != NULL);
dn->dn_phys->dn_nlevels = new_level;
- dprintf("os=%p obj=%llu, increase to %d\n",
- dn->dn_objset, dn->dn_object,
- dn->dn_phys->dn_nlevels);
+ dprintf("os=%p obj=%llu, increase to %d\n", dn->dn_objset,
+ dn->dn_object, dn->dn_phys->dn_nlevels);
/* check for existing blkptrs in the dnode */
for (i = 0; i < nblkptr; i++)
@@ -160,7 +159,7 @@
rw_enter(&db->db_dnode->dn_struct_rwlock, RW_READER);
err = dbuf_hold_impl(db->db_dnode, db->db_level-1,
- (db->db_blkid << epbs) + i, TRUE, FTAG, &child);
+ (db->db_blkid << epbs) + i, TRUE, FTAG, &child);
rw_exit(&db->db_dnode->dn_struct_rwlock);
if (err == ENOENT)
continue;
@@ -367,6 +366,7 @@
for (; db != ▮ db = list_head(&dn->dn_dbufs)) {
list_remove(&dn->dn_dbufs, db);
list_insert_tail(&dn->dn_dbufs, db);
+ ASSERT3P(db->db_dnode, ==, dn);
mutex_enter(&db->db_mtx);
if (db->db_state == DB_EVICTING) {