MCPcopy Create free account
hub / github.com/F-Stack/f-stack / dbuf_assign_arcbuf

Function dbuf_assign_arcbuf

freebsd/contrib/openzfs/module/zfs/dbuf.c:2661–2725  ·  view source on GitHub ↗

* Directly assign a provided arc buf to a given dbuf if it's not referenced * by anybody except our caller. Otherwise copy arcbuf's contents to dbuf. */

Source from the content-addressed store, hash-verified

2659 * by anybody except our caller. Otherwise copy arcbuf's contents to dbuf.
2660 */
2661void
2662dbuf_assign_arcbuf(dmu_buf_impl_t *db, arc_buf_t *buf, dmu_tx_t *tx)
2663{
2664 ASSERT(!zfs_refcount_is_zero(&db->db_holds));
2665 ASSERT(db->db_blkid != DMU_BONUS_BLKID);
2666 ASSERT(db->db_level == 0);
2667 ASSERT3U(dbuf_is_metadata(db), ==, arc_is_metadata(buf));
2668 ASSERT(buf != NULL);
2669 ASSERT3U(arc_buf_lsize(buf), ==, db->db.db_size);
2670 ASSERT(tx->tx_txg != 0);
2671
2672 arc_return_buf(buf, db);
2673 ASSERT(arc_released(buf));
2674
2675 mutex_enter(&db->db_mtx);
2676
2677 while (db->db_state == DB_READ || db->db_state == DB_FILL)
2678 cv_wait(&db->db_changed, &db->db_mtx);
2679
2680 ASSERT(db->db_state == DB_CACHED || db->db_state == DB_UNCACHED);
2681
2682 if (db->db_state == DB_CACHED &&
2683 zfs_refcount_count(&db->db_holds) - 1 > db->db_dirtycnt) {
2684 /*
2685 * In practice, we will never have a case where we have an
2686 * encrypted arc buffer while additional holds exist on the
2687 * dbuf. We don't handle this here so we simply assert that
2688 * fact instead.
2689 */
2690 ASSERT(!arc_is_encrypted(buf));
2691 mutex_exit(&db->db_mtx);
2692 (void) dbuf_dirty(db, tx);
2693 bcopy(buf->b_data, db->db.db_data, db->db.db_size);
2694 arc_buf_destroy(buf, db);
2695 return;
2696 }
2697
2698 if (db->db_state == DB_CACHED) {
2699 dbuf_dirty_record_t *dr = list_head(&db->db_dirty_records);
2700
2701 ASSERT(db->db_buf != NULL);
2702 if (dr != NULL && dr->dr_txg == tx->tx_txg) {
2703 ASSERT(dr->dt.dl.dr_data == db->db_buf);
2704
2705 if (!arc_released(db->db_buf)) {
2706 ASSERT(dr->dt.dl.dr_override_state ==
2707 DR_OVERRIDDEN);
2708 arc_release(db->db_buf, db);
2709 }
2710 dr->dt.dl.dr_data = buf;
2711 arc_buf_destroy(db->db_buf, db);
2712 } else if (dr == NULL || dr->dt.dl.dr_data != db->db_buf) {
2713 arc_release(db->db_buf, db);
2714 arc_buf_destroy(db->db_buf, db);
2715 }
2716 db->db_buf = NULL;
2717 }
2718 ASSERT(db->db_buf == NULL);

Callers 2

receive_spillFunction · 0.85

Calls 15

zfs_refcount_is_zeroFunction · 0.85
dbuf_is_metadataFunction · 0.85
arc_is_metadataFunction · 0.85
arc_buf_lsizeFunction · 0.85
arc_return_bufFunction · 0.85
arc_releasedFunction · 0.85
mutex_enterFunction · 0.85
cv_waitFunction · 0.85
zfs_refcount_countFunction · 0.85
arc_is_encryptedFunction · 0.85
mutex_exitFunction · 0.85
dbuf_dirtyFunction · 0.85

Tested by

no test coverage detected