From 9b18a78c739a2a43c3ed386a4a9c52e4f7360650 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Fri, 23 Apr 2021 23:18:08 -0400 Subject: [PATCH] make-disk-image: Account for the ext4 reserved space Reserved space includes: - inodes space in use (2 blocks per) - about 5.2% of the space The 5.2% reserved space was computed empirically when working on a previous EXT4 image builder. It seems to stabilize around 5% even for much larger filesystems. --- nixos/lib/make-disk-image.nix | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/nixos/lib/make-disk-image.nix b/nixos/lib/make-disk-image.nix index 164f2f0f0be8..f1c942181f04 100644 --- a/nixos/lib/make-disk-image.nix +++ b/nixos/lib/make-disk-image.nix @@ -186,6 +186,13 @@ let format' = format; in let echo "$acc" } + # Approximative percentage of reserved space in an ext4 fs over 512MiB. + # 0.05208587646484375 + # × 1000, integer part: 52 + compute_fudge() { + echo $(( $1 * 52 / 1000 )) + } + mkdir $out root="$PWD/root" @@ -252,15 +259,22 @@ let format' = format; in let ''} # Compute required space in filesystem blocks - requiredSpace=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "${blockSize}" '{}' ';' | cut -f1 | sum_lines) - # Convert to bytes - requiredSpace=$(( requiredSpace * ${blockSize} )) + diskUsage=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "${blockSize}" '{}' ';' | cut -f1 | sum_lines) + # Each inode takes space! + numInodes=$(find . | wc -l) + # Convert to bytes, inodes take two blocks each! + diskUsage=$(( (diskUsage + 2 * numInodes) * ${blockSize} )) + # Then increase the required space to account for the reserved blocks. + fudge=$(compute_fudge $diskUsage) + requiredFilesystemSpace=$(( diskUsage + fudge )) - diskSize=$(( requiredSpace + additionalSpace )) + diskSize=$(( requiredFilesystemSpace + additionalSpace )) truncate -s "$diskSize" $diskImage printf "Automatic disk size...\n" - printf " Space needed: %d bytes\n" $requiredSpace + printf " Closure space use: %d bytes\n" $diskUsage + printf " fudge: %d bytes\n" $fudge + printf " Filesystem size needed: %d bytes\n" $requiredFilesystemSpace printf " Additional space: %d bytes\n" $additionalSpace printf " Disk image size: %d bytes\n" $diskSize '' else ''