Improve caching for dbuf prefetches

To avoid read errors with transaction open dmu_tx_check_ioerr()
is used to read everything required in advance.  But there seems
to be a chance for the buffer to evicted from dbuf cache in
between, which result in immediate eviction from ARC, which may
require additional disk read later in a place where error handling
is problematic.

To partially workaround this introduce a new flag DMU_IS_PREFETCH,
relayed to ARC as ARC_FLAG_PREFETCH | ARC_FLAG_PRESCIENT_PREFETCH,
making ARC delay eviction by at least several seconds, or till the
actual read inside the transaction, that will promote it to demand
access.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #18160
This commit is contained in:
Alexander Motin
2026-02-04 13:12:32 -05:00
committed by GitHub
parent 00d69b0f72
commit 21bbe7cb67
3 changed files with 8 additions and 4 deletions
+3 -1
View File
@@ -1637,6 +1637,8 @@ dbuf_read_impl(dmu_buf_impl_t *db, dnode_t *dn, zio_t *zio, dmu_flags_t flags,
aflags |= ARC_FLAG_UNCACHED;
else if (dbuf_is_l2cacheable(db, bp))
aflags |= ARC_FLAG_L2CACHE;
if (flags & DMU_IS_PREFETCH)
aflags |= ARC_FLAG_PREFETCH | ARC_FLAG_PRESCIENT_PREFETCH;
dbuf_add_ref(db, NULL);
@@ -1769,7 +1771,7 @@ dbuf_read(dmu_buf_impl_t *db, zio_t *pio, dmu_flags_t flags)
mutex_enter(&db->db_mtx);
if (!(flags & (DMU_UNCACHEDIO | DMU_KEEP_CACHING)))
db->db_pending_evict = B_FALSE;
if (flags & DMU_PARTIAL_FIRST)
if (flags & (DMU_PARTIAL_FIRST | DMU_IS_PREFETCH))
db->db_partial_read = B_TRUE;
else if (!(flags & (DMU_PARTIAL_MORE | DMU_KEEP_CACHING)))
db->db_partial_read = B_FALSE;