authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-13 12:14:24+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-16 10:37:19+01:00
log73a65674e4d464c2588eb752da0aa4869c671c0a
treeb4511261368b651538a02a3114a6b6cb2597cfa3
parentc7fed8d0c6efa1ac0c72566cd397acf1210203e3
signaturelock-open Commit is signed but in an unrecognized format.

link.MappedFile: clarify some logic

No functional changes, just a small refactor so I can properly understand what's happening in this logic.

1 files changed, 16 insertions(+), 12 deletions(-)

src/link/MappedFile.zig+16-12
......@@ -856,19 +856,20 @@ fn resizeNode(
856856 ni.setLocationAssumeCapacity(mf, old_offset, new_size);
857857 return;
858858 }
859 if (is_linux and !mf.flags.fallocate_insert_range_unsupported and
860 node.flags.alignment.order(mf.flags.block_size).compare(.gte))
861859 insert_range: {
860 if (!is_linux) break :insert_range;
861 if (mf.flags.fallocate_insert_range_unsupported) break :insert_range;
862
863 // We need the node to be aligned to `mf.flags.block_size` in the file in order to use this
864 // fast path. It is not sufficient to check `node.flags.alignment`, because that doesn't
865 // necessarily mean that all *parent* nodes are equally aligned; instead we must compute the
866 // actual file offset.
862867 const range_file_offset = ni.fileLocation(mf, false).offset + old_size;
863868 const range_size = node.flags.alignment.forward(
864869 @intCast(requested_size +| requested_size / growth_factor),
865870 ) - old_size;
866
867 // If this node is being realigned, its current state might not
868 // meet the requirements for fallocate
869 if (!mf.flags.block_size.check(@intCast(range_file_offset)) or
870 !mf.flags.block_size.check(@intCast(range_size)))
871 break :insert_range;
871 if (!mf.flags.block_size.check(@intCast(range_file_offset))) break :insert_range;
872 if (!mf.flags.block_size.check(@intCast(range_size))) break :insert_range;
872873
873874 mf.memory_map.write(io) catch |err| switch (err) {
874875 error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking
......@@ -1208,9 +1209,11 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
12081209 // make a copy of this node at the new location
12091210 try mf.copyRange(old_file_offset, new_file_offset, size);
12101211 // delete the copy of this node at the old location
1211 if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and
1212 size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)
1213 switch (linux.errno(linux.fallocate(
1212 if (is_linux and
1213 !mf.flags.fallocate_punch_hole_unsupported and
1214 size >= mf.flags.block_size.toByteUnits() * 2 - 1)
1215 {
1216 while (true) switch (linux.errno(linux.fallocate(
12141217 mf.memory_map.file.handle,
12151218 linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,
12161219 @intCast(old_file_offset),
......@@ -1224,13 +1227,14 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
12241227 .NOSPC => return error.NoSpaceLeft,
12251228 .NOSYS, .OPNOTSUPP => {
12261229 mf.flags.fallocate_punch_hole_unsupported = true;
1227 break;
1230 break; // fall back to slow path
12281231 },
12291232 .PERM => return error.PermissionDenied,
12301233 .SPIPE => return error.Unseekable,
12311234 .TXTBSY => return error.FileBusy,
12321235 else => |e| return std.posix.unexpectedErrno(e),
12331236 };
1237 }
12341238 @memset(mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], 0);
12351239}
12361240