311 DB_DNODE_ENTER(db);
312 dn = DB_DNODE(db);
313 if (dn == NULL) {
314 ASSERT(db->db_parent == NULL);
315 ASSERT(db->db_blkptr == NULL);
316 } else {
317 ASSERT3U(db->db.db_object, ==, dn->dn_object);
318 ASSERT3P(db->db_objset, ==, dn->dn_objset);
319 ASSERT3U(db->db_level, <, dn->dn_nlevels);
320 ASSERT(db->db_blkid == DMU_BONUS_BLKID ||
321 db->db_blkid == DMU_SPILL_BLKID ||
322 !list_is_empty(&dn->dn_dbufs));
323 }
324 if (db->db_blkid == DMU_BONUS_BLKID) {
325 ASSERT(dn != NULL);
326 ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
327 ASSERT3U(db->db.db_offset, ==, DMU_BONUS_BLKID);
328 } else if (db->db_blkid == DMU_SPILL_BLKID) {
329 ASSERT(dn != NULL);
330 ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
331 ASSERT3U(db->db.db_offset, ==, 0);
332 } else {
333 ASSERT3U(db->db.db_offset, ==, db->db_blkid * db->db.db_size);
334 }
335
336 for (dr = db->db_data_pending; dr != NULL; dr = dr->dr_next)
337 ASSERT(dr->dr_dbuf == db);
338
339 for (dr = db->db_last_dirty; dr != NULL; dr = dr->dr_next)
340 ASSERT(dr->dr_dbuf == db);
341
342 /*
343 * We can't assert that db_size matches dn_datablksz because it
344 * can be momentarily different when another thread is doing
345 * dnode_set_blksz().
346 */
347 if (db->db_level == 0 && db->db.db_object == DMU_META_DNODE_OBJECT) {
348 dr = db->db_data_pending;
349 /*
350 * It should only be modified in syncing context, so
351 * make sure we only have one copy of the data.
2291
2292 DB_DNODE_ENTER(db);
2293 dn = DB_DNODE(db);
2294
2295 if (db->db_blkid == DMU_SPILL_BLKID) {
2296 mutex_enter(&dn->dn_mtx);
2297 dn->dn_phys->dn_flags |= DNODE_FLAG_SPILL_BLKPTR;
2298 mutex_exit(&dn->dn_mtx);
2299 }
2300
2301 /*
2302 * If this is a bonus buffer, simply copy the bonus data into the
2303 * dnode. It will be written out when the dnode is synced (and it
2304 * will be synced, since it must have been dirty for dbuf_sync to
2305 * be called).
2306 */
2307 if (db->db_blkid == DMU_BONUS_BLKID) {
2308 dbuf_dirty_record_t **drp;
2309
2310 ASSERT(*datap != NULL);
2311 ASSERT3U(db->db_level, ==, 0);
2312 ASSERT3U(dn->dn_phys->dn_bonuslen, <=, DN_MAX_BONUSLEN);
2313 bcopy(*datap, DN_BONUS(dn->dn_phys), dn->dn_phys->dn_bonuslen);
2314 DB_DNODE_EXIT(db);
2315
2316 if (*datap != db->db.db_data) {
2317 zio_buf_free(*datap, DN_MAX_BONUSLEN);
2318 arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
2319 }
2320 db->db_data_pending = NULL;
2321 drp = &db->db_last_dirty;
2322 while (*drp != dr)
2323 drp = &(*drp)->dr_next;
2324 ASSERT(dr->dr_next == NULL);
2325 ASSERT(dr->dr_dbuf == db);
2326 *drp = dr->dr_next;
2327 kmem_free(dr, sizeof (dbuf_dirty_record_t));
2328 ASSERT(db->db_dirtycnt > 0);
2329 db->db_dirtycnt -= 1;
2330 dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
2331 return;
2490 fill += ibp->blk_fill;
2491 }
2492 }
2493 DB_DNODE_EXIT(db);
2494
2495 bp->blk_fill = fill;
2496
2497 mutex_exit(&db->db_mtx);
2498 }
2499
2500 /* ARGSUSED */
2501 static void
2502 dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
2503 {
2504 dmu_buf_impl_t *db = vdb;
2505 blkptr_t *bp = zio->io_bp;
2506 blkptr_t *bp_orig = &zio->io_bp_orig;
2507 uint64_t txg = zio->io_txg;
2508 dbuf_dirty_record_t **drp, *dr;
2509
2510 ASSERT3U(zio->io_error, ==, 0);
2511 ASSERT(db->db_blkptr == bp);
2512
2513 if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
2514 ASSERT(BP_EQUAL(bp, bp_orig));
2515 } else {
2516 objset_t *os;
2517 dsl_dataset_t *ds;
2518 dmu_tx_t *tx;
2519
2520 DB_GET_OBJSET(&os, db);
2521 ds = os->os_dsl_dataset;
2522 tx = os->os_synctx;
2523
2524 (void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
2525 dsl_dataset_block_born(ds, bp, tx);
2526 }
2527
2528 mutex_enter(&db->db_mtx);
2529
2530 DBUF_VERIFY(db);
|
311 DB_DNODE_ENTER(db);
312 dn = DB_DNODE(db);
313 if (dn == NULL) {
314 ASSERT(db->db_parent == NULL);
315 ASSERT(db->db_blkptr == NULL);
316 } else {
317 ASSERT3U(db->db.db_object, ==, dn->dn_object);
318 ASSERT3P(db->db_objset, ==, dn->dn_objset);
319 ASSERT3U(db->db_level, <, dn->dn_nlevels);
320 ASSERT(db->db_blkid == DMU_BONUS_BLKID ||
321 db->db_blkid == DMU_SPILL_BLKID ||
322 !list_is_empty(&dn->dn_dbufs));
323 }
324 if (db->db_blkid == DMU_BONUS_BLKID) {
325 ASSERT(dn != NULL);
326 ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
327 ASSERT3U(db->db.db_offset, ==, DMU_BONUS_BLKID);
328 } else if (db->db_blkid == DMU_SPILL_BLKID) {
329 ASSERT(dn != NULL);
330 ASSERT3U(db->db.db_size, >=, dn->dn_bonuslen);
331 ASSERT0(db->db.db_offset);
332 } else {
333 ASSERT3U(db->db.db_offset, ==, db->db_blkid * db->db.db_size);
334 }
335
336 for (dr = db->db_data_pending; dr != NULL; dr = dr->dr_next)
337 ASSERT(dr->dr_dbuf == db);
338
339 for (dr = db->db_last_dirty; dr != NULL; dr = dr->dr_next)
340 ASSERT(dr->dr_dbuf == db);
341
342 /*
343 * We can't assert that db_size matches dn_datablksz because it
344 * can be momentarily different when another thread is doing
345 * dnode_set_blksz().
346 */
347 if (db->db_level == 0 && db->db.db_object == DMU_META_DNODE_OBJECT) {
348 dr = db->db_data_pending;
349 /*
350 * It should only be modified in syncing context, so
351 * make sure we only have one copy of the data.
2291
2292 DB_DNODE_ENTER(db);
2293 dn = DB_DNODE(db);
2294
2295 if (db->db_blkid == DMU_SPILL_BLKID) {
2296 mutex_enter(&dn->dn_mtx);
2297 dn->dn_phys->dn_flags |= DNODE_FLAG_SPILL_BLKPTR;
2298 mutex_exit(&dn->dn_mtx);
2299 }
2300
2301 /*
2302 * If this is a bonus buffer, simply copy the bonus data into the
2303 * dnode. It will be written out when the dnode is synced (and it
2304 * will be synced, since it must have been dirty for dbuf_sync to
2305 * be called).
2306 */
2307 if (db->db_blkid == DMU_BONUS_BLKID) {
2308 dbuf_dirty_record_t **drp;
2309
2310 ASSERT(*datap != NULL);
2311 ASSERT0(db->db_level);
2312 ASSERT3U(dn->dn_phys->dn_bonuslen, <=, DN_MAX_BONUSLEN);
2313 bcopy(*datap, DN_BONUS(dn->dn_phys), dn->dn_phys->dn_bonuslen);
2314 DB_DNODE_EXIT(db);
2315
2316 if (*datap != db->db.db_data) {
2317 zio_buf_free(*datap, DN_MAX_BONUSLEN);
2318 arc_space_return(DN_MAX_BONUSLEN, ARC_SPACE_OTHER);
2319 }
2320 db->db_data_pending = NULL;
2321 drp = &db->db_last_dirty;
2322 while (*drp != dr)
2323 drp = &(*drp)->dr_next;
2324 ASSERT(dr->dr_next == NULL);
2325 ASSERT(dr->dr_dbuf == db);
2326 *drp = dr->dr_next;
2327 kmem_free(dr, sizeof (dbuf_dirty_record_t));
2328 ASSERT(db->db_dirtycnt > 0);
2329 db->db_dirtycnt -= 1;
2330 dbuf_rele_and_unlock(db, (void *)(uintptr_t)txg);
2331 return;
2490 fill += ibp->blk_fill;
2491 }
2492 }
2493 DB_DNODE_EXIT(db);
2494
2495 bp->blk_fill = fill;
2496
2497 mutex_exit(&db->db_mtx);
2498 }
2499
2500 /* ARGSUSED */
2501 static void
2502 dbuf_write_done(zio_t *zio, arc_buf_t *buf, void *vdb)
2503 {
2504 dmu_buf_impl_t *db = vdb;
2505 blkptr_t *bp = zio->io_bp;
2506 blkptr_t *bp_orig = &zio->io_bp_orig;
2507 uint64_t txg = zio->io_txg;
2508 dbuf_dirty_record_t **drp, *dr;
2509
2510 ASSERT0(zio->io_error);
2511 ASSERT(db->db_blkptr == bp);
2512
2513 if (zio->io_flags & ZIO_FLAG_IO_REWRITE) {
2514 ASSERT(BP_EQUAL(bp, bp_orig));
2515 } else {
2516 objset_t *os;
2517 dsl_dataset_t *ds;
2518 dmu_tx_t *tx;
2519
2520 DB_GET_OBJSET(&os, db);
2521 ds = os->os_dsl_dataset;
2522 tx = os->os_synctx;
2523
2524 (void) dsl_dataset_block_kill(ds, bp_orig, tx, B_TRUE);
2525 dsl_dataset_block_born(ds, bp, tx);
2526 }
2527
2528 mutex_enter(&db->db_mtx);
2529
2530 DBUF_VERIFY(db);
|