mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Raw sends must be able to decrease nlevels
Currently, when a raw zfs send file includes a DRR_OBJECT record that would decrease the number of levels of an existing object, the object is reallocated with dmu_object_reclaim() which creates the new dnode using the old object's nlevels. For non-raw sends this doesn't really matter, but raw sends require that nlevels on the receive side match that of the send side so that the checksum-of-MAC tree can be properly maintained. This patch corrects the issue by freeing the object completely before allocating it again in this case. This patch also corrects several issues with dnode_hold_impl() and related functions that prevented dnodes (particularly multi-slot dnodes) from being reallocated properly due to the fact that existing dnodes were not being fully cleaned up when they were freed. This patch adds a test to make sure that zfs recv functions properly with incremental streams containing dnodes of different sizes. Reviewed by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Jorgen Lundman <lundman@lundman.net> Signed-off-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #6821 Closes #6864
This commit is contained in:
committed by
Brian Behlendorf
parent
d53bd7f524
commit
047116ac76
@@ -657,7 +657,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
|
||||
'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_files', 'send_encrypted_heirarchy',
|
||||
'send_freeobjects']
|
||||
'send_freeobjects', 'send_realloc_dnode_size']
|
||||
tags = ['functional', 'rsend']
|
||||
|
||||
[tests/functional/scrub_mirror]
|
||||
|
||||
@@ -40,4 +40,5 @@ dist_pkgdata_SCRIPTS = \
|
||||
send-c_volume.ksh \
|
||||
send-c_zstreamdump.ksh \
|
||||
send-cpL_varied_recsize.ksh \
|
||||
send_freeobjects.ksh
|
||||
send_freeobjects.ksh \
|
||||
send_realloc_dnode_size.ksh
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/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 slot count.
|
||||
#
|
||||
# Strategy:
|
||||
# 1. Populate a dataset with 1k byte dnodes and snapshot
|
||||
# 2. Remove objects, set dnodesize=legacy, and remount dataset so new objects
|
||||
# get recycled numbers and formerly "interior" dnode slots get assigned
|
||||
# to new objects
|
||||
# 3. Remove objects, set dnodesize=2k, and remount dataset so new objects
|
||||
# overlap with recently recycled and formerly "normal" dnode slots get
|
||||
# assigned to new objects
|
||||
# 4. Generate initial and incremental streams
|
||||
# 5. Verify initial and incremental streams can be received
|
||||
#
|
||||
|
||||
verify_runnable "both"
|
||||
|
||||
log_assert "Verify incremental receive handles objects with changed dnode size"
|
||||
|
||||
function cleanup
|
||||
{
|
||||
rm -f $BACKDIR/fs-dn-legacy
|
||||
rm -f $BACKDIR/fs-dn-1k
|
||||
rm -f $BACKDIR/fs-dn-2k
|
||||
|
||||
if datasetexists $POOL/fs ; then
|
||||
log_must zfs destroy -rR $POOL/fs
|
||||
fi
|
||||
|
||||
if datasetexists $POOL/newfs ; then
|
||||
log_must zfs destroy -rR $POOL/newfs
|
||||
fi
|
||||
}
|
||||
|
||||
log_onexit cleanup
|
||||
|
||||
# 1. Populate a dataset with 1k byte dnodes and snapshot
|
||||
log_must zfs create -o dnodesize=1k $POOL/fs
|
||||
log_must mk_files 200 262144 0 $POOL/fs
|
||||
log_must zfs snapshot $POOL/fs@a
|
||||
|
||||
# 2. Remove objects, set dnodesize=legacy, and remount dataset so new objects
|
||||
# get recycled numbers and formerly "interior" dnode slots get assigned
|
||||
# to new objects
|
||||
rm /$POOL/fs/*
|
||||
|
||||
log_must zfs unmount $POOL/fs
|
||||
log_must zfs set dnodesize=legacy $POOL/fs
|
||||
log_must zfs mount $POOL/fs
|
||||
|
||||
log_must mk_files 200 262144 0 $POOL/fs
|
||||
log_must zfs snapshot $POOL/fs@b
|
||||
|
||||
# 3. Remove objects, set dnodesize=2k, and remount dataset so new objects
|
||||
# overlap with recently recycled and formerly "normal" dnode slots get
|
||||
# assigned to new objects
|
||||
rm /$POOL/fs/*
|
||||
|
||||
log_must zfs unmount $POOL/fs
|
||||
log_must zfs set dnodesize=2k $POOL/fs
|
||||
log_must zfs mount $POOL/fs
|
||||
|
||||
mk_files 200 262144 0 $POOL/fs
|
||||
log_must zfs snapshot $POOL/fs@c
|
||||
|
||||
# 4. Generate initial and incremental streams
|
||||
log_must eval "zfs send $POOL/fs@a > $BACKDIR/fs-dn-1k"
|
||||
log_must eval "zfs send -i $POOL/fs@a $POOL/fs@b > $BACKDIR/fs-dn-legacy"
|
||||
log_must eval "zfs send -i $POOL/fs@b $POOL/fs@c > $BACKDIR/fs-dn-2k"
|
||||
|
||||
# 5. Verify initial and incremental streams can be received
|
||||
log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-1k"
|
||||
log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-legacy"
|
||||
log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs-dn-2k"
|
||||
|
||||
log_pass "Verify incremental receive handles objects with changed dnode size"
|
||||
Reference in New Issue
Block a user