# HG changeset patch # User maybee # Date 1172418649 28800 # Node ID 2226ffbe7873a05ca1297737edfee39bb2b3e22d # Parent bc5b4fa57622357619641ac8b2b8fd11bc29f2dc 6526196 ZFS: assertion failed: zp->z_phys->zp_links > zp_is_dir diff -r bc5b4fa57622 -r 2226ffbe7873 usr/src/cmd/ztest/ztest.c --- a/usr/src/cmd/ztest/ztest.c Fri Feb 23 12:59:39 2007 -0800 +++ b/usr/src/cmd/ztest/ztest.c Sun Feb 25 07:50:49 2007 -0800 @@ -213,6 +213,7 @@ hrtime_t zs_stop_time; uint64_t zs_alloc; uint64_t zs_space; + uint64_t zs_txg; ztest_info_t zs_info[ZTEST_FUNCS]; mutex_t zs_sync_lock[ZTEST_SYNC_LOCKS]; uint64_t zs_seq[ZTEST_SYNC_LOCKS]; @@ -1904,6 +1905,41 @@ } void +ztest_dmu_check_future_leak(objset_t *os, uint64_t txg) +{ + dmu_buf_t *db; + ztest_block_tag_t rbt; + + if (zopt_verbose >= 3) { + char osname[MAXNAMELEN]; + dmu_objset_name(os, osname); + (void) printf("checking %s for future leaks in txg %lld...\n", + osname, (u_longlong_t)txg); + } + + /* + * Make sure that, if there is a write record in the bonus buffer + * of the ZTEST_DIROBJ, that the txg for this record is <= the + * last synced txg of the pool. + */ + + VERIFY(0 == dmu_bonus_hold(os, ZTEST_DIROBJ, FTAG, &db)); + ASSERT3U(db->db_size, ==, sizeof (rbt)); + bcopy(db->db_data, &rbt, db->db_size); + if (rbt.bt_objset != 0) { + ASSERT3U(rbt.bt_objset, ==, dmu_objset_id(os)); + ASSERT3U(rbt.bt_object, ==, ZTEST_DIROBJ); + ASSERT3U(rbt.bt_offset, ==, -1ULL); + if (rbt.bt_txg > txg) { + fatal(0, + "future leak: got %llx, last synced txg is %llx", + rbt.bt_txg, txg); + } + } + dmu_buf_rele(db, FTAG); +} + +void ztest_dmu_write_parallel(ztest_args_t *za) { objset_t *os = za->za_os; @@ -2908,6 +2944,20 @@ * See if it's time to force a crash. */ if (now > za->za_kill) { + dmu_tx_t *tx; + uint64_t txg; + + mutex_enter(&spa_namespace_lock); + tx = dmu_tx_create(za->za_os); + VERIFY(0 == dmu_tx_assign(tx, TXG_NOWAIT)); + txg = dmu_tx_get_txg(tx); + dmu_tx_commit(tx); + zs->zs_txg = txg; + if (zopt_verbose >= 3) + (void) printf( + "killing process after txg %lld\n", + (u_longlong_t)txg); + txg_wait_synced(dmu_objset_pool(za->za_os), txg); zs->zs_alloc = spa_get_alloc(dmu_objset_spa(za->za_os)); zs->zs_space = spa_get_space(dmu_objset_spa(za->za_os)); (void) kill(getpid(), SIGKILL); @@ -3069,11 +3119,14 @@ d = t % zopt_datasets; if (t < zopt_datasets) { ztest_replay_t zr; + int test_future = FALSE; (void) rw_rdlock(&ztest_shared->zs_name_lock); (void) snprintf(name, 100, "%s/%s_%d", pool, pool, d); error = dmu_objset_create(name, DMU_OST_OTHER, NULL, ztest_create_cb, NULL); - if (error != 0 && error != EEXIST) { + if (error == EEXIST) { + test_future = TRUE; + } else if (error != 0) { if (error == ENOSPC) { zs->zs_enospc_count++; (void) rw_unlock( @@ -3089,6 +3142,9 @@ fatal(0, "dmu_objset_open('%s') = %d", name, error); (void) rw_unlock(&ztest_shared->zs_name_lock); + if (test_future && ztest_shared->zs_txg > 0) + ztest_dmu_check_future_leak(za[d].za_os, + ztest_shared->zs_txg); zr.zr_os = za[d].za_os; zil_replay(zr.zr_os, &zr, &zr.zr_assign, ztest_replay_vector); @@ -3109,6 +3165,7 @@ fatal(0, "can't create thread %d: error %d", t, error); } + ztest_shared->zs_txg = 0; while (--t >= 0) { error = thr_join(za[t].za_thread, NULL, NULL); diff -r bc5b4fa57622 -r 2226ffbe7873 usr/src/uts/common/fs/zfs/dbuf.c --- a/usr/src/uts/common/fs/zfs/dbuf.c Fri Feb 23 12:59:39 2007 -0800 +++ b/usr/src/uts/common/fs/zfs/dbuf.c Sun Feb 25 07:50:49 2007 -0800 @@ -640,7 +640,9 @@ ASSERT(db->db_level == 0); ASSERT(db->db.db_object != DMU_META_DNODE_OBJECT); - if (dr == NULL || dr->dt.dl.dr_data != db->db_buf) + if (dr == NULL || + (dr->dt.dl.dr_data != + ((db->db_blkid == DB_BONUS_BLKID) ? db->db.db_data : db->db_buf))) return; /*