]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: skip fallocate test if not supported, and adjust allocation size on darwin
authorCherry Zhang <cherryyz@google.com>
Tue, 30 Jun 2020 20:51:27 +0000 (16:51 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 1 Jul 2020 15:29:29 +0000 (15:29 +0000)
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>

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

index a064bea23d009bb98ff1c7e89b2d232ed9d451f1..51f5fcdd9fc27d6f4e138c40700d9c4474747ab8 100644 (file)
@@ -28,6 +28,21 @@ func TestFallocate(t *testing.T) {
        }
        defer out.Close()
 
+       // Try fallocate first.
+       for {
+               err = out.fallocate(1 << 10)
+               if err == syscall.EOPNOTSUPP { // The underlying file system may not support fallocate
+                       t.Skip("fallocate is not supported")
+               }
+               if err == syscall.EINTR {
+                       continue // try again
+               }
+               if err != nil {
+                       t.Fatalf("fallocate failed: %v", err)
+               }
+               break
+       }
+
        // Mmap 1 MiB initially, and grow to 2 and 3 MiB.
        // Check if the file size and disk usage is expected.
        for _, sz := range []int64{1 << 20, 2 << 20, 3 << 20} {
index 9a74ba875e265cf7648fa043f915608672261472..d7e3372230b0dc682e760894c06c65a0cd662c70 100644 (file)
@@ -14,7 +14,10 @@ func (out *OutBuf) fallocate(size uint64) error {
        if err != nil {
                return err
        }
-       cursize := uint64(stat.Size())
+       // F_PEOFPOSMODE allocates from the end of the file, so we want the size difference.
+       // Apparently, it uses the end of the allocation, instead of the logical end of the
+       // the file.
+       cursize := uint64(stat.Sys().(*syscall.Stat_t).Blocks * 512) // allocated size
        if size <= cursize {
                return nil
        }
@@ -23,7 +26,7 @@ func (out *OutBuf) fallocate(size uint64) error {
                Flags:   syscall.F_ALLOCATEALL,
                Posmode: syscall.F_PEOFPOSMODE,
                Offset:  0,
-               Length:  int64(size - cursize), // F_PEOFPOSMODE allocates from the end of the file, so we want the size difference here
+               Length:  int64(size - cursize),
        }
 
        _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(out.f.Fd()), syscall.F_PREALLOCATE, uintptr(unsafe.Pointer(store)))