Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/sys/unix: the Linux ioctl FIDEDUPERANGE wrapper is implemented wrong #43678

Closed
viric opened this issue Jan 13, 2021 · 3 comments
Closed

x/sys/unix: the Linux ioctl FIDEDUPERANGE wrapper is implemented wrong #43678

viric opened this issue Jan 13, 2021 · 3 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@viric
Copy link

viric commented Jan 13, 2021

What version of Go are you using (go version)?

I use this version below, but I want to talk about code in master (that came from x/sys/unix).

$ go version
go version go1.15.2 linux/amd64

Does this issue reproduce with the latest release?

Yes, a ioctl implementation doesn't match the linux manual.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/viric/.cache/go-build"
GOENV="/home/viric/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/viric/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/viric/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/nix/store/dz12rdqlp94rqinvcmk6knia6cw5s8ra-go-1.15.2/share/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/nix/store/dz12rdqlp94rqinvcmk6knia6cw5s8ra-go-1.15.2/share/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build423744141=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I want to use the (x/)sys/unix IoctlFileDedupeRange function

What did you expect to see?

It should ressemble the ioctl described in the linux manual:

int ioctl(int src_fd, FIDEDUPERANGE, struct file_dedupe_range *arg);

           struct file_dedupe_range {
               __u64 src_offset;
               __u64 src_length;
               __u16 dest_count;
               __u16 reserved1;
               __u32 reserved2;
               struct file_dedupe_range_info info[0];
           };

           struct file_dedupe_range_info {
               __s64 dest_fd;
               __u64 dest_offset;
               __u64 bytes_deduped;
               __s32 status;
               __u32 reserved;
           };

What did you see instead?

This is the ioctl in sys/unix (golang master or x/sys/unix) is like this: https://pkg.go.dev/golang.org/x/sys/unix#IoctlFileDedupeRange

destFd should be srcFd, and the 'info' member is not there, making the call unusable.

func IoctlFileDedupeRange(destFd int, value *FileDedupeRange) error

type FileDedupeRange struct {
    Src_offset uint64
    Src_length uint64
    Dest_count uint16
    Reserved1  uint16
    Reserved2  uint32
}
@ianlancetaylor ianlancetaylor changed the title the sys/unix linux ioctl FIDEDUPERANGE wrapper is implemented wrong x/sys/unix: the Linux ioctl FIDEDUPERANGE wrapper is implemented wrong Jan 13, 2021
@gopherbot gopherbot added this to the Unreleased milestone Jan 13, 2021
@ianlancetaylor
Copy link
Contributor

CC @tklauser

@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 13, 2021
@KyleSanderson
Copy link

Funny enough I'm looking to use this as well, then saw the incorrect and incomplete definition in golang 😕. Google lead me here, which was nice.

Go code cannot refer to zero-sized fields that occur at the end of non-empty C structs. To get the address of such a field (which is the only operation you can do with a zero-sized field) you must take the address of the struct and add the size of the struct.

Specifically the bug here is file_dedupe_range_info is not implemented, which allows the syscall to still happen, but it doesn't do any work because Dest_count can only be 0 due to the bug.

@gopherbot
Copy link

Change https://golang.org/cl/284352 mentions this issue: sys/unix: fix and test the FIDEDUPERANGE Linux ioctl

@golang golang locked and limited conversation to collaborators Feb 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants