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

Open directories using O_SEARCH #228

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ go_deps_dev.module_override(
patches = ["//:patches/org_golang_x_oauth2/injectable-clock.diff"],
path = "golang.org/x/oauth2",
)
go_deps_dev.module_override(
patches = ["//:patches/org_golang_x_sys/o-search.diff"],
path = "golang.org/x/sys",
)
go_deps_dev.module_override(
patches = ["//:patches/org_uber_go_mock/mocks-for-funcs.diff"],
path = "go.uber.org/mock",
Expand Down
40 changes: 40 additions & 0 deletions patches/org_golang_x_sys/o-search.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
diff --git unix/zerrors_darwin_amd64.go unix/zerrors_darwin_amd64.go
index d73c465..d406964 100644
--- unix/zerrors_darwin_amd64.go
+++ unix/zerrors_darwin_amd64.go
@@ -1128,6 +1128,7 @@ const (
O_DSYNC = 0x400000
O_EVTONLY = 0x8000
O_EXCL = 0x800
+ O_EXEC = 0x40000000
O_EXLOCK = 0x20
O_FSYNC = 0x80
O_NDELAY = 0x4
@@ -1138,6 +1139,7 @@ const (
O_POPUP = 0x80000000
O_RDONLY = 0x0
O_RDWR = 0x2
+ O_SEARCH = 0x40100000
O_SHLOCK = 0x10
O_SYMLINK = 0x200000
O_SYNC = 0x80
diff --git unix/zerrors_darwin_arm64.go unix/zerrors_darwin_arm64.go
index 4a55a40..c47c6e9 100644
--- unix/zerrors_darwin_arm64.go
+++ unix/zerrors_darwin_arm64.go
@@ -1128,6 +1128,7 @@ const (
O_DSYNC = 0x400000
O_EVTONLY = 0x8000
O_EXCL = 0x800
+ O_EXEC = 0x40000000
O_EXLOCK = 0x20
O_FSYNC = 0x80
O_NDELAY = 0x4
@@ -1138,6 +1139,7 @@ const (
O_POPUP = 0x80000000
O_RDONLY = 0x0
O_RDWR = 0x2
+ O_SEARCH = 0x40100000
O_SHLOCK = 0x10
O_SYMLINK = 0x200000
O_SYNC = 0x80
2 changes: 2 additions & 0 deletions pkg/filesystem/local_directory_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
// rawDeviceNumber is the equivalent of POSIX dev_t.
type rawDeviceNumber = int32

const oflagSearch = unix.O_SEARCH

func (d *localDirectory) Mknod(name path.Component, perm os.FileMode, deviceNumber DeviceNumber) error {
return status.Error(codes.Unimplemented, "Creation of device nodes is not supported on Darwin")
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/filesystem/local_directory_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import (

"github.com/buildbarn/bb-storage/pkg/filesystem/path"

"golang.org/x/sys/unix"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

// rawDeviceNumber is the equivalent of POSIX dev_t.
type rawDeviceNumber = uint64

const oflagSearch = unix.O_SEARCH

func (d *localDirectory) Mknod(name path.Component, perm os.FileMode, deviceNumber DeviceNumber) error {
// Though mknodat() exists on FreeBSD, device nodes created
// outside of devfs are non-functional.
Expand Down
2 changes: 2 additions & 0 deletions pkg/filesystem/local_directory_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
// rawDeviceNumber is the equivalent of POSIX dev_t.
type rawDeviceNumber = uint64

const oflagSearch = unix.O_PATH

func (d *localDirectory) Mknod(name path.Component, perm os.FileMode, deviceNumber DeviceNumber) error {
defer runtime.KeepAlive(d)

Expand Down
18 changes: 15 additions & 3 deletions pkg/filesystem/local_directory_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewLocalDirectory(directoryParser path.Parser) (DirectoryCloser, error) {
return nil, util.StatusWrap(err, "Failed to create local representation of directory")
}

fd, err := unix.Openat(unix.AT_FDCWD, pathString, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_RDONLY, 0)
fd, err := unix.Openat(unix.AT_FDCWD, pathString, unix.O_DIRECTORY|unix.O_NOFOLLOW|oflagSearch, 0)
if err != nil {
return nil, err
}
Expand All @@ -53,7 +53,7 @@ func NewLocalDirectory(directoryParser path.Parser) (DirectoryCloser, error) {
func (d *localDirectory) enter(name path.Component) (*localDirectory, error) {
defer runtime.KeepAlive(d)

fd, err := unix.Openat(d.fd, name.String(), unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_RDONLY, 0)
fd, err := unix.Openat(d.fd, name.String(), unix.O_DIRECTORY|unix.O_NOFOLLOW|oflagSearch, 0)
if err != nil {
if runtime.GOOS == "freebsd" && err == syscall.EMLINK {
// FreeBSD erroneously returns EMLINK.
Expand Down Expand Up @@ -406,7 +406,19 @@ func (d *localDirectory) Symlink(oldName path.Parser, newName path.Component) er
func (d *localDirectory) Sync() error {
defer runtime.KeepAlive(d)

return unix.Fsync(d.fd)
// Linux doesn't permit calling fsync() on directories opened
// with O_PATH. Reopen the directory with O_RDONLY.
dfd := d.fd
if runtime.GOOS == "linux" {
var err error
dfd, err = unix.Openat(d.fd, ".", unix.O_DIRECTORY|unix.O_RDONLY, 0)
if err != nil {
return err
}
defer unix.Close(dfd)
}

return unix.Fsync(dfd)
}

func (d *localDirectory) Chtimes(name path.Component, atime, mtime time.Time) error {
Expand Down
Loading