Skip to content

Commit a4ba411

Browse files
committed
cmd/link: skip fallocate test if not supported, and adjust allocation size on darwin
On Linux, the linker uses fallocate to preallocate the output file storage. The underlying file system may not support fallocate, causing the test to fail. Skip the test in this case. On darwin, apparently F_PREALLOCATE allocates from the end of the allocation instead of the logical end of the file. Adjust the size calculation. Fixes #39905. Change-Id: I01e676737fd2619ebbdba05c7cf7f424ec27de35 Reviewed-on: https://go-review.googlesource.com/c/go/+/240618 Reviewed-by: Than McIntosh <thanm@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
1 parent 7799756 commit a4ba411

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/cmd/link/internal/ld/fallocate_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ func TestFallocate(t *testing.T) {
2828
}
2929
defer out.Close()
3030

31+
// Try fallocate first.
32+
for {
33+
err = out.fallocate(1 << 10)
34+
if err == syscall.EOPNOTSUPP { // The underlying file system may not support fallocate
35+
t.Skip("fallocate is not supported")
36+
}
37+
if err == syscall.EINTR {
38+
continue // try again
39+
}
40+
if err != nil {
41+
t.Fatalf("fallocate failed: %v", err)
42+
}
43+
break
44+
}
45+
3146
// Mmap 1 MiB initially, and grow to 2 and 3 MiB.
3247
// Check if the file size and disk usage is expected.
3348
for _, sz := range []int64{1 << 20, 2 << 20, 3 << 20} {

src/cmd/link/internal/ld/outbuf_darwin.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ func (out *OutBuf) fallocate(size uint64) error {
1414
if err != nil {
1515
return err
1616
}
17-
cursize := uint64(stat.Size())
17+
// F_PEOFPOSMODE allocates from the end of the file, so we want the size difference.
18+
// Apparently, it uses the end of the allocation, instead of the logical end of the
19+
// the file.
20+
cursize := uint64(stat.Sys().(*syscall.Stat_t).Blocks * 512) // allocated size
1821
if size <= cursize {
1922
return nil
2023
}
@@ -23,7 +26,7 @@ func (out *OutBuf) fallocate(size uint64) error {
2326
Flags: syscall.F_ALLOCATEALL,
2427
Posmode: syscall.F_PEOFPOSMODE,
2528
Offset: 0,
26-
Length: int64(size - cursize), // F_PEOFPOSMODE allocates from the end of the file, so we want the size difference here
29+
Length: int64(size - cursize),
2730
}
2831

2932
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(out.f.Fd()), syscall.F_PREALLOCATE, uintptr(unsafe.Pointer(store)))

0 commit comments

Comments
 (0)