diff options
author | Fabricio Voznika <fvoznika@google.com> | 2018-10-31 11:27:10 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-10-31 11:28:27 -0700 |
commit | ccc3d7ca11a2a623587c651a6690aaa46d2c2665 (patch) | |
tree | baa04e2e5ebe4a1ee638dbfbbd86dbcbc613696c /runsc/fsgofer/fsgofer_unsafe.go | |
parent | e9dbd5ab67bc31e59910930e6c1b551c0fd05ee6 (diff) |
Make lazy open the mode of operation for fsgofer
With recent changes to 9P server, path walks are now safe inside
open, create, rename and setattr calls. To simplify the code, remove
the lazyopen=false mode that was used for bind mounts, and converge
all mounts to using lazy open.
PiperOrigin-RevId: 219508628
Change-Id: I073e7e1e2e9a9972d150eaf4cb29e553997a9b76
Diffstat (limited to 'runsc/fsgofer/fsgofer_unsafe.go')
-rw-r--r-- | runsc/fsgofer/fsgofer_unsafe.go | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go index 99bc25ec1..94413db86 100644 --- a/runsc/fsgofer/fsgofer_unsafe.go +++ b/runsc/fsgofer/fsgofer_unsafe.go @@ -19,20 +19,29 @@ import ( "unsafe" "gvisor.googlesource.com/gvisor/pkg/abi/linux" + "gvisor.googlesource.com/gvisor/pkg/syserr" ) func statAt(dirFd int, name string) (syscall.Stat_t, error) { nameBytes, err := syscall.BytePtrFromString(name) if err != nil { - return syscall.Stat_t{}, extractErrno(err) + return syscall.Stat_t{}, err } - namePtr := uintptr(unsafe.Pointer(nameBytes)) + namePtr := unsafe.Pointer(nameBytes) var stat syscall.Stat_t - statPtr := uintptr(unsafe.Pointer(&stat)) + statPtr := unsafe.Pointer(&stat) - if _, _, err := syscall.Syscall6(syscall.SYS_NEWFSTATAT, uintptr(dirFd), namePtr, statPtr, linux.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 { - return syscall.Stat_t{}, err + if _, _, errno := syscall.Syscall6( + syscall.SYS_NEWFSTATAT, + uintptr(dirFd), + uintptr(namePtr), + uintptr(statPtr), + linux.AT_SYMLINK_NOFOLLOW, + 0, + 0); errno != 0 { + + return syscall.Stat_t{}, syserr.FromHost(errno).ToError() } return stat, nil } @@ -40,19 +49,59 @@ func statAt(dirFd int, name string) (syscall.Stat_t, error) { func utimensat(dirFd int, name string, times [2]syscall.Timespec, flags int) error { // utimensat(2) doesn't accept empty name, instead name must be nil to make it // operate directly on 'dirFd' unlike other *at syscalls. - var namePtr uintptr + var namePtr unsafe.Pointer if name != "" { nameBytes, err := syscall.BytePtrFromString(name) if err != nil { - return extractErrno(err) + return err + } + namePtr = unsafe.Pointer(nameBytes) + } + + timesPtr := unsafe.Pointer(×[0]) + + if _, _, errno := syscall.Syscall6( + syscall.SYS_UTIMENSAT, + uintptr(dirFd), + uintptr(namePtr), + uintptr(timesPtr), + uintptr(flags), + 0, + 0); errno != 0 { + + return syserr.FromHost(errno).ToError() + } + return nil +} + +func renameat(oldDirFD int, oldName string, newDirFD int, newName string) error { + var oldNamePtr unsafe.Pointer + if oldName != "" { + nameBytes, err := syscall.BytePtrFromString(oldName) + if err != nil { + return err + } + oldNamePtr = unsafe.Pointer(nameBytes) + } + var newNamePtr unsafe.Pointer + if newName != "" { + nameBytes, err := syscall.BytePtrFromString(newName) + if err != nil { + return err } - namePtr = uintptr(unsafe.Pointer(nameBytes)) + newNamePtr = unsafe.Pointer(nameBytes) } - timesPtr := uintptr(unsafe.Pointer(×[0])) + if _, _, errno := syscall.Syscall6( + syscall.SYS_RENAMEAT, + uintptr(oldDirFD), + uintptr(oldNamePtr), + uintptr(newDirFD), + uintptr(newNamePtr), + 0, + 0); errno != 0 { - if _, _, err := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirFd), namePtr, timesPtr, uintptr(flags), 0, 0); err != 0 { - return err + return syserr.FromHost(errno).ToError() } return nil } |