Changeset View
Changeset View
Standalone View
Standalone View
sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c
Show First 20 Lines • Show All 1,071 Lines • ▼ Show 20 Lines | |||||
struct arc_buf_hdr { | struct arc_buf_hdr { | ||||
/* protected by hash lock */ | /* protected by hash lock */ | ||||
dva_t b_dva; | dva_t b_dva; | ||||
uint64_t b_birth; | uint64_t b_birth; | ||||
arc_buf_contents_t b_type; | arc_buf_contents_t b_type; | ||||
arc_buf_hdr_t *b_hash_next; | arc_buf_hdr_t *b_hash_next; | ||||
arc_flags_t b_flags; | arc_flags_t b_flags; | ||||
enum zio_zstd_levels b_complevel; | |||||
/* | /* | ||||
* This field stores the size of the data buffer after | * This field stores the size of the data buffer after | ||||
* compression, and is set in the arc's zio completion handlers. | * compression, and is set in the arc's zio completion handlers. | ||||
* It is in units of SPA_MINBLOCKSIZE (e.g. 1 == 512 bytes). | * It is in units of SPA_MINBLOCKSIZE (e.g. 1 == 512 bytes). | ||||
* | * | ||||
* While the block pointers can store up to 32MB in their psize | * While the block pointers can store up to 32MB in their psize | ||||
* field, we can only store up to 32MB minus 512B. This is due | * field, we can only store up to 32MB minus 512B. This is due | ||||
▲ Show 20 Lines • Show All 820 Lines • ▼ Show 20 Lines | arc_cksum_is_equal(arc_buf_hdr_t *hdr, zio_t *zio) | ||||
* pool. When this is the case, we must first compress it if it is | * pool. When this is the case, we must first compress it if it is | ||||
* compressed on the main pool before we can validate the checksum. | * compressed on the main pool before we can validate the checksum. | ||||
*/ | */ | ||||
if (!HDR_COMPRESSION_ENABLED(hdr) && compress != ZIO_COMPRESS_OFF) { | if (!HDR_COMPRESSION_ENABLED(hdr) && compress != ZIO_COMPRESS_OFF) { | ||||
ASSERT3U(HDR_GET_COMPRESS(hdr), ==, ZIO_COMPRESS_OFF); | ASSERT3U(HDR_GET_COMPRESS(hdr), ==, ZIO_COMPRESS_OFF); | ||||
uint64_t lsize = HDR_GET_LSIZE(hdr); | uint64_t lsize = HDR_GET_LSIZE(hdr); | ||||
uint64_t csize; | uint64_t csize; | ||||
abd_t *cdata = abd_alloc_linear(HDR_GET_PSIZE(hdr), B_TRUE); | abd_t *cdata = abd_alloc_linear(lsize, B_TRUE); | ||||
csize = zio_compress_data(compress, zio->io_abd, | csize = zio_compress_data(compress, zio->io_abd, | ||||
abd_to_buf(cdata), lsize); | abd_to_buf(cdata), lsize, &zio->io_prop); | ||||
ASSERT3U(csize, <=, HDR_GET_PSIZE(hdr)); | if (csize == 0 || csize == lsize) { | ||||
/* Compression has failed */ | |||||
/* XXX: Should we retry here? */ | |||||
return (B_FALSE); | |||||
} | |||||
if (csize > HDR_GET_PSIZE(hdr)) { | |||||
/* | |||||
* Compression produced a larger output, the checksum | |||||
* cannot possibly match. | |||||
*/ | |||||
return (B_FALSE); | |||||
} | |||||
if (csize < HDR_GET_PSIZE(hdr)) { | if (csize < HDR_GET_PSIZE(hdr)) { | ||||
/* | /* | ||||
* Compressed blocks are always a multiple of the | * Compressed blocks are always a multiple of the | ||||
* smallest ashift in the pool. Ideally, we would | * smallest ashift in the pool. Ideally, we would | ||||
* like to round up the csize to the next | * like to round up the csize to the next | ||||
* spa_min_ashift but that value may have changed | * spa_min_ashift but that value may have changed | ||||
* since the block was last written. Instead, | * since the block was last written. Instead, | ||||
* we rely on the fact that the hdr's psize | * we rely on the fact that the hdr's psize | ||||
▲ Show 20 Lines • Show All 3,284 Lines • ▼ Show 20 Lines | if (BP_SHOULD_BYTESWAP(zio->io_bp)) { | ||||
hdr->b_l1hdr.b_byteswap = DMU_BSWAP_UINT64; | hdr->b_l1hdr.b_byteswap = DMU_BSWAP_UINT64; | ||||
} else { | } else { | ||||
hdr->b_l1hdr.b_byteswap = | hdr->b_l1hdr.b_byteswap = | ||||
DMU_OT_BYTESWAP(BP_GET_TYPE(zio->io_bp)); | DMU_OT_BYTESWAP(BP_GET_TYPE(zio->io_bp)); | ||||
} | } | ||||
} else { | } else { | ||||
hdr->b_l1hdr.b_byteswap = DMU_BSWAP_NUMFUNCS; | hdr->b_l1hdr.b_byteswap = DMU_BSWAP_NUMFUNCS; | ||||
} | } | ||||
if (BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_ZSTD) { | |||||
hdr->b_complevel = zio->io_prop.zp_zstd_level; | |||||
} | } | ||||
} | |||||
arc_hdr_clear_flags(hdr, ARC_FLAG_L2_EVICTED); | arc_hdr_clear_flags(hdr, ARC_FLAG_L2_EVICTED); | ||||
if (l2arc_noprefetch && HDR_PREFETCH(hdr)) | if (l2arc_noprefetch && HDR_PREFETCH(hdr)) | ||||
arc_hdr_clear_flags(hdr, ARC_FLAG_L2CACHE); | arc_hdr_clear_flags(hdr, ARC_FLAG_L2CACHE); | ||||
callback_list = hdr->b_l1hdr.b_acb; | callback_list = hdr->b_l1hdr.b_acb; | ||||
ASSERT3P(callback_list, !=, NULL); | ASSERT3P(callback_list, !=, NULL); | ||||
▲ Show 20 Lines • Show All 1,000 Lines • ▼ Show 20 Lines | if (l2arc) | ||||
arc_hdr_set_flags(hdr, ARC_FLAG_L2CACHE); | arc_hdr_set_flags(hdr, ARC_FLAG_L2CACHE); | ||||
if (ARC_BUF_COMPRESSED(buf)) { | if (ARC_BUF_COMPRESSED(buf)) { | ||||
/* | /* | ||||
* We're writing a pre-compressed buffer. Make the | * We're writing a pre-compressed buffer. Make the | ||||
* compression algorithm requested by the zio_prop_t match | * compression algorithm requested by the zio_prop_t match | ||||
* the pre-compressed buffer's compression algorithm. | * the pre-compressed buffer's compression algorithm. | ||||
*/ | */ | ||||
localprop.zp_compress = HDR_GET_COMPRESS(hdr); | localprop.zp_compress = HDR_GET_COMPRESS(hdr); | ||||
if (localprop.zp_compress == ZIO_COMPRESS_ZSTD) { | |||||
localprop.zp_zstd_level = hdr->b_complevel; | |||||
} | |||||
ASSERT3U(HDR_GET_LSIZE(hdr), !=, arc_buf_size(buf)); | ASSERT3U(HDR_GET_LSIZE(hdr), !=, arc_buf_size(buf)); | ||||
zio_flags |= ZIO_FLAG_RAW; | zio_flags |= ZIO_FLAG_RAW; | ||||
} | } | ||||
callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP); | callback = kmem_zalloc(sizeof (arc_write_callback_t), KM_SLEEP); | ||||
callback->awcb_ready = ready; | callback->awcb_ready = ready; | ||||
callback->awcb_children_ready = children_ready; | callback->awcb_children_ready = children_ready; | ||||
callback->awcb_physdone = physdone; | callback->awcb_physdone = physdone; | ||||
▲ Show 20 Lines • Show All 1,098 Lines • ▼ Show 20 Lines | l2arc_read_done(zio_t *zio) | ||||
/* | /* | ||||
* Check this survived the L2ARC journey. | * Check this survived the L2ARC journey. | ||||
*/ | */ | ||||
ASSERT3P(zio->io_abd, ==, hdr->b_l1hdr.b_pabd); | ASSERT3P(zio->io_abd, ==, hdr->b_l1hdr.b_pabd); | ||||
zio->io_bp_copy = cb->l2rcb_bp; /* XXX fix in L2ARC 2.0 */ | zio->io_bp_copy = cb->l2rcb_bp; /* XXX fix in L2ARC 2.0 */ | ||||
zio->io_bp = &zio->io_bp_copy; /* XXX fix in L2ARC 2.0 */ | zio->io_bp = &zio->io_bp_copy; /* XXX fix in L2ARC 2.0 */ | ||||
if (BP_GET_COMPRESS(zio->io_bp) == ZIO_COMPRESS_ZSTD) { | |||||
zio->io_prop.zp_zstd_level = hdr->b_complevel; | |||||
} | |||||
valid_cksum = arc_cksum_is_equal(hdr, zio); | valid_cksum = arc_cksum_is_equal(hdr, zio); | ||||
if (valid_cksum && zio->io_error == 0 && !HDR_L2_EVICTED(hdr)) { | if (valid_cksum && zio->io_error == 0 && !HDR_L2_EVICTED(hdr)) { | ||||
mutex_exit(hash_lock); | mutex_exit(hash_lock); | ||||
zio->io_private = hdr; | zio->io_private = hdr; | ||||
arc_read_done(zio); | arc_read_done(zio); | ||||
} else { | } else { | ||||
mutex_exit(hash_lock); | mutex_exit(hash_lock); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 670 Lines • Show Last 20 Lines |