Skip to content

Commit 75f4140

Browse files
committed
BRT: Fix holes cloning.
- When reading L0 block pointers handle buffers without ones and without dirty records as a holes. Those appear when dnode size was increased, but the end was never written, so there are no new indirection levels to store the pointers. It makes no sense to return EAGAIN here, since sync won't create new indirection levels until there will be actual writes. - When cloning blocks set destination hole logical birth time to the current TXG. Otherwise if we are cloning over existing data, newly created holes may not be properly replicated later. Use BP_SET_BIRTH() when possible to not replicate its logic. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Alexander Motin <[email protected]> Sponsored by: iXsystems, Inc. Closes openzfs#15994 Closes openzfs#16007
1 parent 8477add commit 75f4140

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

module/zfs/dmu.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,11 +2265,13 @@ dmu_read_l0_bps(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
22652265

22662266
if (bp == NULL) {
22672267
/*
2268-
* The block was created in this transaction group,
2269-
* so it has no BP yet.
2268+
* The file size was increased, but the block was never
2269+
* written, otherwise we would either have the block
2270+
* pointer or the dirty record and would not get here.
2271+
* It is effectively a hole, so report it as such.
22702272
*/
2271-
error = SET_ERROR(EAGAIN);
2272-
goto out;
2273+
BP_ZERO(&bps[i]);
2274+
continue;
22732275
}
22742276
/*
22752277
* Make sure we clone only data blocks.
@@ -2361,18 +2363,16 @@ dmu_brt_clone(objset_t *os, uint64_t object, uint64_t offset, uint64_t length,
23612363
ASSERT3U(dr->dr_txg, ==, tx->tx_txg);
23622364
dl = &dr->dt.dl;
23632365
dl->dr_overridden_by = *bp;
2364-
dl->dr_brtwrite = B_TRUE;
2365-
dl->dr_override_state = DR_OVERRIDDEN;
2366-
if (BP_IS_HOLE(bp)) {
2367-
dl->dr_overridden_by.blk_birth = 0;
2368-
dl->dr_overridden_by.blk_phys_birth = 0;
2369-
} else {
2370-
dl->dr_overridden_by.blk_birth = dr->dr_txg;
2366+
if (!BP_IS_HOLE(bp) || bp->blk_birth != 0) {
23712367
if (!BP_IS_EMBEDDED(bp)) {
2372-
dl->dr_overridden_by.blk_phys_birth =
2373-
BP_PHYSICAL_BIRTH(bp);
2368+
BP_SET_BIRTH(&dl->dr_overridden_by, dr->dr_txg,
2369+
BP_PHYSICAL_BIRTH(bp));
2370+
} else {
2371+
dl->dr_overridden_by.blk_birth = dr->dr_txg;
23742372
}
23752373
}
2374+
dl->dr_brtwrite = B_TRUE;
2375+
dl->dr_override_state = DR_OVERRIDDEN;
23762376

23772377
mutex_exit(&db->db_mtx);
23782378

0 commit comments

Comments
 (0)