github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/link/ld/fallocate_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build darwin || (freebsd && go1.21) || linux 6 7 package ld 8 9 import ( 10 "errors" 11 "os" 12 "path/filepath" 13 "syscall" 14 "testing" 15 ) 16 17 func TestFallocate(t *testing.T) { 18 dir := t.TempDir() 19 filename := filepath.Join(dir, "a.out") 20 out := NewOutBuf(nil) 21 err := out.Open(filename) 22 if err != nil { 23 t.Fatalf("Open file failed: %v", err) 24 } 25 defer out.Close() 26 27 // Try fallocate first. 28 for { 29 err = out.fallocate(1 << 10) 30 if errors.Is(err, errors.ErrUnsupported) || err == errNoFallocate { // The underlying file system may not support fallocate 31 t.Skip("fallocate is not supported") 32 } 33 if err == syscall.EINTR { 34 continue // try again 35 } 36 if err != nil { 37 t.Fatalf("fallocate failed: %v", err) 38 } 39 break 40 } 41 42 // Mmap 1 MiB initially, and grow to 2 and 3 MiB. 43 // Check if the file size and disk usage is expected. 44 for _, sz := range []int64{1 << 20, 2 << 20, 3 << 20} { 45 err = out.Mmap(uint64(sz)) 46 if err != nil { 47 t.Fatalf("Mmap failed: %v", err) 48 } 49 stat, err := os.Stat(filename) 50 if err != nil { 51 t.Fatalf("Stat failed: %v", err) 52 } 53 if got := stat.Size(); got != sz { 54 t.Errorf("unexpected file size: got %d, want %d", got, sz) 55 } 56 // The number of blocks must be enough for the requested size. 57 // We used to require an exact match, but it appears that 58 // some file systems allocate a few extra blocks in some cases. 59 // See issue #41127. 60 if got, want := stat.Sys().(*syscall.Stat_t).Blocks, (sz+511)/512; got < want { 61 t.Errorf("unexpected disk usage: got %d blocks, want at least %d", got, want) 62 } 63 out.munmap() 64 } 65 }