Skip to content

sync.verifyBlockCopy fails when target partition is larger than source #403

@eriknordmark

Description

@eriknordmark

Summary

sync.CopyPartitionRaw is intended to support copying a smaller source partition into a larger target — e.g. as the byte-level copy step when growing a partition before renaming it into place. But the post-copy verification in sync/verify.go rejects this case:

if size != expectedSize {
    return fmt.Errorf("target partition size %d is different than expected size %d", size, expectedSize)
}

targetPart.ReadContents reads the full target partition's bytes and returns the full size, even when paired with a NewLimitWriter(...) that only feeds the leading expectedSize bytes into the hasher. So whenever targetSize > sourceSize, the size assertion fails and CopyPartitionRaw returns an error even though the actual byte copy succeeded.

Reproducer

// Two-partition GPT, source=8MB, target=24MB, both filled
// with arbitrary bytes. Then:
err := sync.CopyPartitionRaw(d, sourcePartIdx, targetPartIdx)
// err: "verification failed for partition N: target partition size 25165824
//       is different than expected size 8388608"

A real reproducer is in diskfs/partitionresizer (its raw-copy path is the same CopyPartitionRaw call); the partition-grow flow there is currently blocked end-to-end on this verification.

Suggested fix

In verifyBlockCopy (sync/verify.go:14), when reading the target's bytes for hashing, either:

  1. Use a size-limited reader that only reads expectedSize bytes from the target (and asserts the limit was reached), or
  2. Hash both source and target only over their leading expectedSize bytes, and drop the size-equality check for the target.

Either keeps the byte-equality verification intact while making the function correct for the "target larger than source" case, which is the natural shape when growing a partition.

Impact

Any caller using CopyPartitionRaw to copy a smaller filesystem into a larger partition (squashfs / unknown-FS grow workflows) hits this. partitionresizer's grow-with-raw-copy path is blocked until this is fixed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions