Skip to content

Commit 1631616

Browse files
committed
MappedFile: fix the insert range path not updating the root node
1 parent 7b92d5f commit 1631616

File tree

1 file changed

+48
-51
lines changed

1 file changed

+48
-51
lines changed

src/link/MappedFile.zig

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub const Node = extern struct {
146146

147147
pub fn hasMoved(ni: Node.Index, mf: *const MappedFile) bool {
148148
var parent_ni = ni;
149-
while (parent_ni != .none) {
149+
while (parent_ni != Node.Index.root) {
150150
const parent = parent_ni.get(mf);
151151
if (parent.flags.moved) return true;
152152
parent_ni = parent.parent;
@@ -164,7 +164,7 @@ pub const Node = extern struct {
164164
}
165165
fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void {
166166
var parent_ni = ni;
167-
while (parent_ni != .none) {
167+
while (parent_ni != Node.Index.root) {
168168
const parent_node = parent_ni.get(mf);
169169
if (parent_node.flags.moved) return;
170170
parent_ni = parent_node.parent;
@@ -585,56 +585,55 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
585585
continue;
586586
}
587587
const range_file_offset = ni.fileLocation(mf, false).offset + old_size;
588-
retry: while (true) {
589-
switch (linux.E.init(linux.fallocate(
590-
mf.file.handle,
591-
linux.FALLOC.FL_INSERT_RANGE,
592-
@intCast(range_file_offset),
593-
@intCast(range_size),
594-
))) {
595-
.SUCCESS => {
596-
var enclosing_ni = ni;
597-
while (enclosing_ni != .none) {
588+
while (true) switch (linux.E.init(linux.fallocate(
589+
mf.file.handle,
590+
linux.FALLOC.FL_INSERT_RANGE,
591+
@intCast(range_file_offset),
592+
@intCast(range_size),
593+
))) {
594+
.SUCCESS => {
595+
var enclosing_ni = ni;
596+
while (true) {
597+
try mf.ensureCapacityForSetLocation(gpa);
598+
const enclosing = enclosing_ni.get(mf);
599+
const enclosing_offset, const enclosing_size =
600+
enclosing.location().resolve(mf);
601+
enclosing_ni.setLocationAssumeCapacity(
602+
mf,
603+
enclosing_offset,
604+
enclosing_size + range_size,
605+
);
606+
if (enclosing_ni == Node.Index.root) break;
607+
var after_ni = enclosing.next;
608+
while (after_ni != .none) {
598609
try mf.ensureCapacityForSetLocation(gpa);
599-
const enclosing = enclosing_ni.get(mf);
600-
const enclosing_offset, const enclosing_size =
601-
enclosing.location().resolve(mf);
602-
enclosing_ni.setLocationAssumeCapacity(
610+
const after = after_ni.get(mf);
611+
const after_offset, const after_size = after.location().resolve(mf);
612+
after_ni.setLocationAssumeCapacity(
603613
mf,
604-
enclosing_offset,
605-
enclosing_size + range_size,
614+
range_size + after_offset,
615+
after_size,
606616
);
607-
var after_ni = enclosing.next;
608-
while (after_ni != .none) {
609-
try mf.ensureCapacityForSetLocation(gpa);
610-
const after = after_ni.get(mf);
611-
const after_offset, const after_size = after.location().resolve(mf);
612-
after_ni.setLocationAssumeCapacity(
613-
mf,
614-
range_size + after_offset,
615-
after_size,
616-
);
617-
after_ni = after.next;
618-
}
619-
enclosing_ni = enclosing.parent;
617+
after_ni = after.next;
620618
}
621-
return;
622-
},
623-
.INTR => continue :retry,
624-
.BADF, .FBIG, .INVAL => unreachable,
625-
.IO => return error.InputOutput,
626-
.NODEV => return error.NotFile,
627-
.NOSPC => return error.NoSpaceLeft,
628-
.NOSYS, .OPNOTSUPP => {
629-
mf.flags.fallocate_insert_range_unsupported = true;
630-
break :insert_range;
631-
},
632-
.PERM => return error.PermissionDenied,
633-
.SPIPE => return error.Unseekable,
634-
.TXTBSY => return error.FileBusy,
635-
else => |e| return std.posix.unexpectedErrno(e),
636-
}
637-
}
619+
enclosing_ni = enclosing.parent;
620+
}
621+
return;
622+
},
623+
.INTR => continue,
624+
.BADF, .FBIG, .INVAL => unreachable,
625+
.IO => return error.InputOutput,
626+
.NODEV => return error.NotFile,
627+
.NOSPC => return error.NoSpaceLeft,
628+
.NOSYS, .OPNOTSUPP => {
629+
mf.flags.fallocate_insert_range_unsupported = true;
630+
break :insert_range;
631+
},
632+
.PERM => return error.PermissionDenied,
633+
.SPIPE => return error.Unseekable,
634+
.TXTBSY => return error.FileBusy,
635+
else => |e| return std.posix.unexpectedErrno(e),
636+
};
638637
}
639638
switch (node.next) {
640639
.none => {
@@ -728,7 +727,6 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
728727
// delete the copy of this node at the old location
729728
if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and
730729
size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true)
731-
{
732730
switch (linux.E.init(linux.fallocate(
733731
mf.file.handle,
734732
linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE,
@@ -749,8 +747,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
749747
.SPIPE => return error.Unseekable,
750748
.TXTBSY => return error.FileBusy,
751749
else => |e| return std.posix.unexpectedErrno(e),
752-
}
753-
};
750+
};
754751
@memset(mf.contents[@intCast(old_file_offset)..][0..@intCast(size)], 0);
755752
}
756753

0 commit comments

Comments
 (0)