Handle new dnode size in incremental backup stream
When receiving an incremental backup stream, call dmu_object_reclaim_dnsize() if an object's dnode size differs between the incremental source and target. Otherwise it may appear that a dnode which has shrunk is still occupying slots which are in fact free. This will cause a failure to receive new objects that should occupy the now-free slots. Add a test case to verify that an incremental stream containing objects with changed dnode sizes can be received without error. This test case fails without this change. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ned Bass <bass6@llnl.gov> Closes #6366 Closes #6576
This commit is contained in:
parent
c8811dec70
commit
65dcb0f67a
|
@ -2482,11 +2482,13 @@ receive_object(struct receive_writer_arg *rwa, struct drr_object *drro,
|
|||
} else if (drro->drr_type != doi.doi_type ||
|
||||
drro->drr_blksz != doi.doi_data_block_size ||
|
||||
drro->drr_bonustype != doi.doi_bonus_type ||
|
||||
drro->drr_bonuslen != doi.doi_bonus_size) {
|
||||
drro->drr_bonuslen != doi.doi_bonus_size ||
|
||||
drro->drr_dn_slots != (doi.doi_dnodesize >> DNODE_SHIFT)) {
|
||||
/* currently allocated, but with different properties */
|
||||
err = dmu_object_reclaim(rwa->os, drro->drr_object,
|
||||
err = dmu_object_reclaim_dnsize(rwa->os, drro->drr_object,
|
||||
drro->drr_type, drro->drr_blksz,
|
||||
drro->drr_bonustype, drro->drr_bonuslen, tx);
|
||||
drro->drr_bonustype, drro->drr_bonuslen,
|
||||
drro->drr_dn_slots << DNODE_SHIFT, tx);
|
||||
}
|
||||
if (err != 0) {
|
||||
dmu_tx_commit(tx);
|
||||
|
|
|
@ -520,7 +520,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
|
|||
'send-c_lz4_disabled', 'send-c_recv_lz4_disabled',
|
||||
'send-c_mixed_compression', 'send-c_stream_size_estimate', 'send-cD',
|
||||
'send-c_embedded_blocks', 'send-c_resume', 'send-cpL_varied_recsize',
|
||||
'send-c_recv_dedup', 'send_encrypted_heirarchy']
|
||||
'send-c_recv_dedup', 'send_encrypted_heirarchy', 'send_changed_dnodesize']
|
||||
|
||||
[tests/functional/scrub_mirror]
|
||||
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
|
||||
|
|
|
@ -23,6 +23,7 @@ dist_pkgdata_SCRIPTS = \
|
|||
rsend_021_pos.ksh \
|
||||
rsend_022_pos.ksh \
|
||||
rsend_024_pos.ksh \
|
||||
send_changed_dnodesize.ksh \
|
||||
send_encrypted_heirarchy.ksh \
|
||||
send-cD.ksh \
|
||||
send-c_embedded_blocks.ksh \
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/ksh
|
||||
|
||||
#
|
||||
# This file and its contents are supplied under the terms of the
|
||||
# Common Development and Distribution License ("CDDL"), version 1.0.
|
||||
# You may only use this file in accordance with the terms of version
|
||||
# 1.0 of the CDDL.
|
||||
#
|
||||
# A full copy of the text of the CDDL should have accompanied this
|
||||
# source. A copy of the CDDL is also available via the Internet at
|
||||
# http://www.illumos.org/license/CDDL.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2017 by Lawrence Livermore National Security, LLC.
|
||||
#
|
||||
|
||||
. $STF_SUITE/include/libtest.shlib
|
||||
. $STF_SUITE/tests/functional/rsend/rsend.kshlib
|
||||
|
||||
#
|
||||
# Description:
|
||||
# Verify incremental receive properly handles objects with changed
|
||||
# dnode size.
|
||||
#
|
||||
# Strategy:
|
||||
# 1. Populate a dataset with dnodesize=auto with objects
|
||||
# 2. Take a snapshot
|
||||
# 3. Remove objects and set dnodesize=legacy
|
||||
# 4. Remount dataset so object numbers get recycled and formerly
|
||||
# "interior" dnode slots get assigned to new objects
|
||||
# 5. Repopulate dataset
|
||||
# 6. Send first snapshot to new dataset
|
||||
# 7. Send incremental snapshot from second snapshot to new dataset
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "Verify incremental receive handles objects with changed dnode size"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
rm -f $BACKDIR/fs-dn-auto
|
||||
rm -f $BACKDIR/fs-dn-legacy
|
||||
}
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
log_must zfs create -o dnodesize=auto $POOL/fs
|
||||
mk_files 200 262144 0 $POOL/fs
|
||||
log_must zfs unmount $POOL/fs
|
||||
log_must zfs snapshot $POOL/fs@a
|
||||
log_must zfs mount $POOL/fs
|
||||
log_must rm /$POOL/fs/*
|
||||
log_must zfs unmount $POOL/fs
|
||||
log_must zfs set dnodesize=legacy $POOL/fs
|
||||
log_must zfs mount $POOL/fs
|
||||
mk_files 200 262144 0 $POOL/fs
|
||||
log_must zfs unmount $POOL/fs
|
||||
log_must zfs snapshot $POOL/fs@b
|
||||
log_must eval "zfs send $POOL/fs@a > $BACKDIR/fs-dn-auto"
|
||||
log_must eval "zfs send -i $POOL/fs@a $POOL/fs@b > $BACKDIR/fs-dn-legacy"
|
||||
log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-auto"
|
||||
log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-legacy"
|
||||
|
||||
log_pass "Verify incremental receive handles objects with changed dnode size"
|
Loading…
Reference in New Issue