Skip to content

Commit 96ce0b6

Browse files
committed
zio: make io_bp_copy be a separate allocation
We only need our own copy of the BP if the caller provided one that they would free before we're done with it. Additionally, L2ARC currently abuses io_bp_copy to smuggle the originally BP back to arc_read_done() inside the L2ARC read ZIO. A small helper function is provided to handle that allocation when necessary. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Rob Norris <[email protected]>
1 parent 032380a commit 96ce0b6

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

include/sys/zio.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ struct zio {
486486
spa_t *io_spa;
487487
blkptr_t *io_bp;
488488
blkptr_t *io_bp_override;
489-
blkptr_t io_bp_copy;
489+
blkptr_t *io_bp_copy;
490490
list_t io_parent_list;
491491
list_t io_child_list;
492492
zio_t *io_logical;
@@ -687,6 +687,8 @@ extern void zio_resume_wait(spa_t *spa);
687687
extern int zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp,
688688
enum blk_config_flag blk_config, enum blk_verify_flag blk_verify);
689689

690+
extern void zio_force_bp(zio_t *zio, const blkptr_t *bp);
691+
690692
/*
691693
* Initial setup and teardown.
692694
*/

module/zfs/arc.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8964,8 +8964,7 @@ l2arc_read_done(zio_t *zio)
89648964
*/
89658965
ASSERT(zio->io_abd == hdr->b_l1hdr.b_pabd ||
89668966
(HDR_HAS_RABD(hdr) && zio->io_abd == hdr->b_crypt_hdr.b_rabd));
8967-
zio->io_bp_copy = cb->l2rcb_bp; /* XXX fix in L2ARC 2.0 */
8968-
zio->io_bp = &zio->io_bp_copy; /* XXX fix in L2ARC 2.0 */
8967+
zio_force_bp(zio, &cb->l2rcb_bp); /* XXX fix in L2ARC 2.0 */
89698968
zio->io_prop.zp_complevel = hdr->b_complevel;
89708969

89718970
valid_cksum = arc_cksum_is_equal(hdr, zio);

module/zfs/zio.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -992,8 +992,10 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp,
992992
if (bp != NULL) {
993993
if (type != ZIO_TYPE_WRITE ||
994994
zio->io_child_type == ZIO_CHILD_DDT) {
995-
zio->io_bp_copy = *bp;
996-
zio->io_bp = &zio->io_bp_copy; /* so caller can free */
995+
zio->io_bp_copy =
996+
kmem_cache_alloc(zio_bp_cache, KM_SLEEP);
997+
*zio->io_bp_copy = *bp;
998+
zio->io_bp = zio->io_bp_copy; /* so caller can free */
997999
} else {
9981000
zio->io_bp = (blkptr_t *)bp;
9991001
}
@@ -1054,9 +1056,30 @@ zio_destroy(zio_t *zio)
10541056
list_destroy(&zio->io_child_list);
10551057
mutex_destroy(&zio->io_lock);
10561058
cv_destroy(&zio->io_cv);
1059+
if (zio->io_bp_copy != NULL)
1060+
kmem_cache_free(zio_bp_cache, zio->io_bp_copy);
10571061
kmem_cache_free(zio_cache, zio);
10581062
}
10591063

1064+
/*
1065+
* Forcibly set the block pointer in a completed ZIO. This is only used from
1066+
* l2arc_read_done() to set the original BP on the L2ARC read ZIO so that it
1067+
* looks sensible when sent back to arc_read_done(). Shouldn't be used anywhere
1068+
* else. If that changes,
1069+
* that is, you do something about the "XXX fix in L2ARC 2.0" comment in arc.c
1070+
* that has existed since prehistory, please rewrite this comment too.
1071+
*/
1072+
void
1073+
zio_force_bp(zio_t *zio, const blkptr_t *bp)
1074+
{
1075+
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
1076+
ASSERT3U(zio->io_stage, ==, ZIO_STAGE_DONE);
1077+
ASSERT0P(zio->io_bp_copy);
1078+
zio->io_bp_copy = kmem_cache_alloc(zio_bp_cache, KM_SLEEP);
1079+
*zio->io_bp_copy = *bp;
1080+
zio->io_bp = zio->io_bp_copy;
1081+
}
1082+
10601083
/*
10611084
* ZIO intended to be between others. Provides synchronization at READY
10621085
* and DONE pipeline stages and calls the respective callbacks.
@@ -1814,7 +1837,7 @@ zio_read_bp_init(zio_t *zio)
18141837
uint64_t psize =
18151838
BP_IS_EMBEDDED(bp) ? BPE_GET_PSIZE(bp) : BP_GET_PSIZE(bp);
18161839

1817-
ASSERT3P(zio->io_bp, ==, &zio->io_bp_copy);
1840+
ASSERT3P(zio->io_bp, ==, zio->io_bp_copy);
18181841

18191842
if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF &&
18201843
zio->io_child_type == ZIO_CHILD_LOGICAL &&
@@ -2142,7 +2165,7 @@ zio_free_bp_init(zio_t *zio)
21422165
zio->io_pipeline = ZIO_DDT_FREE_PIPELINE;
21432166
}
21442167

2145-
ASSERT3P(zio->io_bp, ==, &zio->io_bp_copy);
2168+
ASSERT3P(zio->io_bp, ==, zio->io_bp_copy);
21462169

21472170
return (zio);
21482171
}
@@ -5308,8 +5331,12 @@ zio_ready(zio_t *zio)
53085331
}
53095332

53105333
#ifdef ZFS_DEBUG
5311-
if (bp != NULL && bp != &zio->io_bp_copy)
5312-
zio->io_bp_copy = *bp;
5334+
if (bp != NULL && bp != zio->io_bp_copy) {
5335+
if (zio->io_bp_copy == NULL)
5336+
zio->io_bp_copy =
5337+
kmem_cache_alloc(zio_bp_cache, KM_SLEEP);
5338+
*zio->io_bp_copy = *bp;
5339+
}
53135340
#endif
53145341

53155342
if (zio->io_error != 0) {
@@ -5455,9 +5482,11 @@ zio_done(zio_t *zio)
54555482
ASSERT0(zio->io_children[c][w]);
54565483

54575484
if (zio->io_bp != NULL && !BP_IS_EMBEDDED(zio->io_bp)) {
5458-
ASSERT(memcmp(zio->io_bp, &zio->io_bp_copy,
5459-
sizeof (blkptr_t)) == 0 ||
5460-
(zio->io_bp == zio_unique_parent(zio)->io_bp));
5485+
if (zio->io_bp_copy) {
5486+
ASSERT(memcmp(zio->io_bp, zio->io_bp_copy,
5487+
sizeof (blkptr_t)) == 0 ||
5488+
(zio->io_bp == zio_unique_parent(zio)->io_bp));
5489+
}
54615490
if (zio->io_type == ZIO_TYPE_WRITE && !BP_IS_HOLE(zio->io_bp) &&
54625491
zio->io_bp_override == NULL &&
54635492
!(zio->io_flags & ZIO_FLAG_IO_REPAIR)) {

0 commit comments

Comments
 (0)