| ... | ... | @@ -856,19 +856,20 @@ fn resizeNode( |
| 856 | 856 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); |
| 857 | 857 | return; |
| 858 | 858 | } |
| 859 | | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and |
| 860 | | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) |
| 861 | 859 | 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. |
| 862 | 867 | const range_file_offset = ni.fileLocation(mf, false).offset + old_size; |
| 863 | 868 | const range_size = node.flags.alignment.forward( |
| 864 | 869 | @intCast(requested_size +| requested_size / growth_factor), |
| 865 | 870 | ) - 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; |
| 872 | 873 | |
| 873 | 874 | mf.memory_map.write(io) catch |err| switch (err) { |
| 874 | 875 | 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: |
| 1208 | 1209 | // make a copy of this node at the new location |
| 1209 | 1210 | try mf.copyRange(old_file_offset, new_file_offset, size); |
| 1210 | 1211 | // 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( |
| 1214 | 1217 | mf.memory_map.file.handle, |
| 1215 | 1218 | linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE, |
| 1216 | 1219 | @intCast(old_file_offset), |
| ... | ... | @@ -1224,13 +1227,14 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 1224 | 1227 | .NOSPC => return error.NoSpaceLeft, |
| 1225 | 1228 | .NOSYS, .OPNOTSUPP => { |
| 1226 | 1229 | mf.flags.fallocate_punch_hole_unsupported = true; |
| 1227 | | break; |
| 1230 | break; // fall back to slow path |
| 1228 | 1231 | }, |
| 1229 | 1232 | .PERM => return error.PermissionDenied, |
| 1230 | 1233 | .SPIPE => return error.Unseekable, |
| 1231 | 1234 | .TXTBSY => return error.FileBusy, |
| 1232 | 1235 | else => |e| return std.posix.unexpectedErrno(e), |
| 1233 | 1236 | }; |
| 1237 | } |
| 1234 | 1238 | @memset(mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], 0); |
| 1235 | 1239 | } |
| 1236 | 1240 | |