Skip to content

Commit

Permalink
unix: offs2lohi should shift by bits, not bytes
Browse files Browse the repository at this point in the history
Fixes golang/go#57291

Change-Id: I212ab8a9f47563d9c124a0f20c17df35d7aa8e6d
Reviewed-on: https://go-review.googlesource.com/c/sys/+/457315
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
  • Loading branch information
ericlagergren authored and gopherbot committed Dec 15, 2022
1 parent cffae8e commit 72f772c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
8 changes: 3 additions & 5 deletions unix/syscall_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1986,12 +1986,10 @@ func bytes2iovec(bs [][]byte) []Iovec {
return iovecs
}

// offs2lohi splits offs into its lower and upper unsigned long. On 64-bit
// systems, hi will always be 0. On 32-bit systems, offs will be split in half.
// preadv/pwritev chose this calling convention so they don't need to add a
// padding-register for alignment on ARM.
// offs2lohi splits offs into its low and high order bits.
func offs2lohi(offs int64) (lo, hi uintptr) {
return uintptr(offs), uintptr(uint64(offs) >> SizeofLong)
const longBits = SizeofLong * 8
return uintptr(offs), uintptr(uint64(offs) >> longBits)
}

func Readv(fd int, iovs [][]byte) (n int, err error) {
Expand Down
33 changes: 33 additions & 0 deletions unix/syscall_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1099,3 +1099,36 @@ func TestIoctlFileDedupeRange(t *testing.T) {
dedupe.Info[1].Bytes_deduped, 0)
}
}

// TestPwritevOffsets tests golang.org/issues/57291 where
// offs2lohi was shifting by the size of long in bytes, not bits.
func TestPwritevOffsets(t *testing.T) {
path := filepath.Join(t.TempDir(), "x.txt")

f, err := os.Create(path)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { f.Close() })

const (
off = 20
)
b := [][]byte{{byte(0)}}
n, err := unix.Pwritev(int(f.Fd()), b, off)
if err != nil {
t.Fatal(err)
}
if n != len(b) {
t.Fatalf("expected to write %d, wrote %d", len(b), n)
}

info, err := f.Stat()
if err != nil {
t.Fatal(err)
}
want := off + int64(len(b))
if info.Size() != want {
t.Fatalf("expected size to be %d, got %d", want, info.Size())
}
}

0 comments on commit 72f772c

Please sign in to comment.