| ... | ... | @@ -146,7 +146,7 @@ pub const Node = extern struct { |
| 146 | 146 | |
| 147 | 147 | pub fn hasMoved(ni: Node.Index, mf: *const MappedFile) bool { |
| 148 | 148 | var parent_ni = ni; |
| 149 | | while (parent_ni != .none) { |
| 149 | while (parent_ni != Node.Index.root) { |
| 150 | 150 | const parent = parent_ni.get(mf); |
| 151 | 151 | if (parent.flags.moved) return true; |
| 152 | 152 | parent_ni = parent.parent; |
| ... | ... | @@ -164,7 +164,7 @@ pub const Node = extern struct { |
| 164 | 164 | } |
| 165 | 165 | fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void { |
| 166 | 166 | var parent_ni = ni; |
| 167 | | while (parent_ni != .none) { |
| 167 | while (parent_ni != Node.Index.root) { |
| 168 | 168 | const parent_node = parent_ni.get(mf); |
| 169 | 169 | if (parent_node.flags.moved) return; |
| 170 | 170 | parent_ni = parent_node.parent; |
| ... | ... | @@ -550,9 +550,9 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 550 | 550 | const new_size = node.flags.alignment.forward(@intCast(requested_size)); |
| 551 | 551 | // Resize the entire file |
| 552 | 552 | if (ni == Node.Index.root) { |
| 553 | try mf.ensureCapacityForSetLocation(gpa); |
| 553 | 554 | try mf.file.setEndPos(new_size); |
| 554 | 555 | try mf.ensureTotalCapacity(@intCast(new_size)); |
| 555 | | try mf.ensureCapacityForSetLocation(gpa); |
| 556 | 556 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); |
| 557 | 557 | return; |
| 558 | 558 | } |
| ... | ... | @@ -585,56 +585,56 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 585 | 585 | continue; |
| 586 | 586 | } |
| 587 | 587 | 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 old_enclosing_size = |
| 600 | enclosing.location().resolve(mf); |
| 601 | const new_enclosing_size = old_enclosing_size + range_size; |
| 602 | enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size); |
| 603 | if (enclosing_ni == Node.Index.root) { |
| 604 | assert(enclosing_offset == 0); |
| 605 | try mf.ensureTotalCapacity(@intCast(new_enclosing_size)); |
| 606 | break; |
| 607 | } |
| 608 | var after_ni = enclosing.next; |
| 609 | while (after_ni != .none) { |
| 598 | 610 | 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( |
| 611 | const after = after_ni.get(mf); |
| 612 | const after_offset, const after_size = after.location().resolve(mf); |
| 613 | after_ni.setLocationAssumeCapacity( |
| 603 | 614 | mf, |
| 604 | | enclosing_offset, |
| 605 | | enclosing_size + range_size, |
| 615 | range_size + after_offset, |
| 616 | after_size, |
| 606 | 617 | ); |
| 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; |
| 618 | after_ni = after.next; |
| 620 | 619 | } |
| 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 | | } |
| 620 | enclosing_ni = enclosing.parent; |
| 621 | } |
| 622 | return; |
| 623 | }, |
| 624 | .INTR => continue, |
| 625 | .BADF, .FBIG, .INVAL => unreachable, |
| 626 | .IO => return error.InputOutput, |
| 627 | .NODEV => return error.NotFile, |
| 628 | .NOSPC => return error.NoSpaceLeft, |
| 629 | .NOSYS, .OPNOTSUPP => { |
| 630 | mf.flags.fallocate_insert_range_unsupported = true; |
| 631 | break :insert_range; |
| 632 | }, |
| 633 | .PERM => return error.PermissionDenied, |
| 634 | .SPIPE => return error.Unseekable, |
| 635 | .TXTBSY => return error.FileBusy, |
| 636 | else => |e| return std.posix.unexpectedErrno(e), |
| 637 | }; |
| 638 | 638 | } |
| 639 | 639 | switch (node.next) { |
| 640 | 640 | .none => { |
| ... | ... | @@ -728,7 +728,6 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 728 | 728 | // delete the copy of this node at the old location |
| 729 | 729 | if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and |
| 730 | 730 | size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true) |
| 731 | | { |
| 732 | 731 | switch (linux.E.init(linux.fallocate( |
| 733 | 732 | mf.file.handle, |
| 734 | 733 | linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE, |
| ... | ... | @@ -749,8 +748,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 749 | 748 | .SPIPE => return error.Unseekable, |
| 750 | 749 | .TXTBSY => return error.FileBusy, |
| 751 | 750 | else => |e| return std.posix.unexpectedErrno(e), |
| 752 | | } |
| 753 | | }; |
| 751 | }; |
| 754 | 752 | @memset(mf.contents[@intCast(old_file_offset)..][0..@intCast(size)], 0); |
| 755 | 753 | } |
| 756 | 754 | |