Skip to content

mount/manager: set sparse file attribute on Windows before mkfs#12938

Draft
djs55 wants to merge 1 commit intocontainerd:mainfrom
djs55:speed-up-windows-mkfs
Draft

mount/manager: set sparse file attribute on Windows before mkfs#12938
djs55 wants to merge 1 commit intocontainerd:mainfrom
djs55:speed-up-windows-mkfs

Conversation

@djs55
Copy link
Copy Markdown

@djs55 djs55 commented Feb 25, 2026

(slightly experimental, still being tested)

On Windows (NTFS/ReFS), extending a file with Truncate does not create a sparse file by default. When mkfs.ext4 subsequently writes metadata at scattered offsets across the file, NTFS must zero-fill all intervening blocks up to the valid data length before each write. For large filesystem images this is extremely slow.

Fix this by marking the file as sparse via FSCTL_SET_SPARSE before calling Truncate. This allows NTFS to leave unwritten regions unallocated, matching the behavior of macOS/Linux where Truncate already produces sparse files.

Benchmark results (8 GB file, Windows 11, NTFS):

  Without FSCTL_SET_SPARSE (before):
    Create + Truncate:    535µs   (on-disk: 8192 MB)
    Scattered writes:     4.74s   (on-disk: 8192 MB)
    Total:                4.74s

  With FSCTL_SET_SPARSE (after):
    Create + Truncate:    526µs   (on-disk: 0 MB)
    Scattered writes:     15.6ms  (on-disk: 1 MB)
    Total:                16.1ms

~300x speedup for the file creation + write pattern, and on-disk usage drops from 8 GB to only the blocks actually written by mkfs.

On Windows (NTFS/ReFS), extending a file with Truncate does not create
a sparse file by default. When mkfs.ext4 subsequently writes metadata
at scattered offsets across the file, NTFS must zero-fill all
intervening blocks up to the valid data length before each write. For
large filesystem images this is extremely slow.

Fix this by marking the file as sparse via FSCTL_SET_SPARSE before
calling Truncate. This allows NTFS to leave unwritten regions
unallocated, matching the behavior of macOS/Linux where Truncate
already produces sparse files.

Benchmark results (8 GB file, Windows 11, NTFS):

  Without FSCTL_SET_SPARSE (before):
    Create + Truncate:    535µs   (on-disk: 8192 MB)
    Scattered writes:     4.74s   (on-disk: 8192 MB)
    Total:                4.74s

  With FSCTL_SET_SPARSE (after):
    Create + Truncate:    526µs   (on-disk: 0 MB)
    Scattered writes:     15.6ms  (on-disk: 1 MB)
    Total:                16.1ms

~300x speedup for the file creation + write pattern, and on-disk usage
drops from 8 GB to only the blocks actually written by mkfs.

Signed-off-by: David Scott <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@github-project-automation github-project-automation Bot moved this to Needs Triage in Pull Request Review Feb 25, 2026
djs55 added a commit to djs55/containerd that referenced this pull request Feb 25, 2026
Signed-off-by: David Scott <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
dmcgowan added a commit to dmcgowan/containerd that referenced this pull request Mar 6, 2026
dmcgowan added a commit to dmcgowan/containerd that referenced this pull request Mar 7, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 7, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 7, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 7, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 7, 2026
github-actions Bot added a commit to akerouanton/containerd that referenced this pull request Mar 8, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 9, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 10, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 10, 2026
@dmcgowan
Copy link
Copy Markdown
Member

@djs55 is this good to go now? Seems the testing of it has been successful

github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 19, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 19, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Mar 19, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Apr 1, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Apr 4, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Apr 10, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Apr 11, 2026
github-actions Bot added a commit to dmcgowan/containerd that referenced this pull request Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

3 participants