Mercurial > illumos > illumos-gate
changeset 4312:4fef416ca8cb
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()
author | gw25295 |
---|---|
date | Thu, 24 May 2007 12:18:14 -0700 |
parents | 27c974ce5d7f |
children | ce5fb9ac11f5 |
files | usr/src/uts/common/fs/zfs/dbuf.c usr/src/uts/common/fs/zfs/dnode_sync.c |
diffstat | 2 files changed, 20 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- 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) {