Skip to content

Compressed receive with different ashift can result in incorrect PSIZE on disk #8462

Closed
@pcd1193182

Description

@pcd1193182

System information

N/A, problem found from code inspection, verified on Illumos

Describe the problem you're observing

When performing a compressed send, the PSIZE of the block is used as the compressed_size of the record. When the receiving system receives these records, they do a raw write, taking the compressed data and writing it directly to disk. When the sending pool has disks with ashift=9 and the receiving system has disks with ashift=12, this result in a bug.

For normal writes, zio_write_compress rounds the PSIZE of the blkptr up to the ashift of the smallest ashift device. For raw writes, this step is bypassed. Instead, the zio's io_size is used directly as the psize. The zio's io_size comes from the arc buf header's size via dbuf_sync_leaf -> dbuf_write -> arc_write -> zio_write. The arc buf header's size is set to be the compressed_size of the record in receive_read_record . Since this size is from a system with a different set of ashifts, this can result in a situation where a block is stored using 4kb on disk, but the psize is only 512 bytes.

So far the only negative effect of this issue I've found is that the dataset's bookkeeping is messed up, resulting in incorrect lrefer and compression ratio statistics. There may be other issues lurking, however.

Describe how to reproduce the problem

  1. Create a pool on a system with ashift=9 disks, and a pool on a system with ashift=12 disks (or set spa_min_ashift when creating the second pool).
  2. Create a filesystem with compression enabled on the source pool.
  3. Populate that filesystem with compressible data.
  4. Snapshot that filesystem
  5. Send that filesystem with -c, and receive it on the target pool.
  6. Verify that the asize is incorrect using zdb -vvvvv to examine the block pointers.

Include any warning/errors/backtraces from the system logs

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions