openzfs/zfs

DRR_WRITE_EMBEDDED records need to include their own byteswap info

Open

#5,854 opened on Mar 2, 2017

View on GitHub
 (9 comments) (0 reactions) (0 assignees)C (9,908 stars) (1,703 forks)batch import
Bot: Not StaleStatus: Understoodgood first issue

Description

Describe the problem you're observing

Doing a zfs send -e from LE to BE and back to LE will cause the dataset to be corrupted. This happens because DRR_WRITE_EMBEDDED records are sent exactly as they are on disk. Both the send and receive code assumes that these embedded blocks will be in the host byteorder. When sending from LE to BE, the BE system knows to store the data with the appropriate byteorder flag set. However, when sending the data back to a LE system, the receive side assumes that all data being sent is in the sending side's byteorder, even though these embedded blocks are not. This also works in reverse (from BE to LE and back).

Describe how to reproduce the problem

[LE system]
zfs create compression=on pool/test
mkdir /pool/test/a
zdb -dddddddd pool/test 7
zfs snap pool/test@now
zfs send -e pool/test@now > sendfile
# move sendfile to other system

[BE system]
zfs recv pool/recv < sendfile
zfs send -e pool/recv@now > sendfile2
# move sendfile2 to other system

[LE system]
zfs recv pool/recv < sendfile2
# at this point you will get warnings about how the dataset can't be mounted

This problem has implications for #5769 as well, particularly the raw sends I am working on now. Since encrypted blocks cannot be byteswapped before they are decrypted, raw sends will have to correctly send byteorder information for each block as well (although raw sends will also need to do this for DRR_WRITE and DRR_SPILL blocks as well). My current WIP solution for this is to add a flag DRR_RAW_BYTESWAP to drr_flags which is set on the send side if BP_SHOULD_BYTESWAP(). This can be interpreted on the recv side to detrmine whether or not to set the byteswap flag on the bp.

This solution may not be appropriate for this problem, however, because current systems will not know how to interpret this new flag.

Contributor guide