summaryrefslogtreecommitdiffhomepage
path: root/runsc/fsgofer/fsgofer_unsafe.go
diff options
context:
space:
mode:
authorAyush Ranjan <ayushranjan@google.com>2021-09-21 14:07:09 -0700
committergVisor bot <gvisor-bot@google.com>2021-09-21 14:09:18 -0700
commit6fccc185609e37b0e3346f8df91bdcb37bc990db (patch)
tree073420614d4dfbc5c13617633d99b38c050e0a86 /runsc/fsgofer/fsgofer_unsafe.go
parente819029f3ad059bfc1635b7f2a196c332fa7532f (diff)
[lisa] Implement lisafs protocol methods in VFS2 gofer client and fsgofer.
Introduces RPC methods in lisafs. Makes that gofer client use lisafs RPCs instead of p9 when lisafs is enabled. Implements the handlers for those methods in fsgofer. Fixes #5465 PiperOrigin-RevId: 398080310
Diffstat (limited to 'runsc/fsgofer/fsgofer_unsafe.go')
-rw-r--r--runsc/fsgofer/fsgofer_unsafe.go30
1 files changed, 30 insertions, 0 deletions
diff --git a/runsc/fsgofer/fsgofer_unsafe.go b/runsc/fsgofer/fsgofer_unsafe.go
index f11fea40d..fb4fbe0d2 100644
--- a/runsc/fsgofer/fsgofer_unsafe.go
+++ b/runsc/fsgofer/fsgofer_unsafe.go
@@ -21,6 +21,8 @@ import (
"gvisor.dev/gvisor/pkg/syserr"
)
+var unixDirentMaxSize uint32 = uint32(unsafe.Sizeof(unix.Dirent{}))
+
func utimensat(dirFd int, name string, times [2]unix.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.
@@ -80,3 +82,31 @@ func renameat(oldDirFD int, oldName string, newDirFD int, newName string) error
}
return nil
}
+
+func parseDirents(buf []byte, handleDirent func(ino uint64, off int64, ftype uint8, name string) bool) {
+ for len(buf) > 0 {
+ // Interpret the buf populated by unix.Getdents as unix.Dirent.
+ dirent := *(*unix.Dirent)(unsafe.Pointer(&buf[0]))
+
+ // Extracting the name is pretty tedious...
+ var nameBuf [unix.NAME_MAX]byte
+ var nameLen int
+ for i := 0; i < len(dirent.Name); i++ {
+ // The name is null terminated.
+ if dirent.Name[i] == 0 {
+ nameLen = i
+ break
+ }
+ nameBuf[i] = byte(dirent.Name[i])
+ }
+ name := string(nameBuf[:nameLen])
+
+ // Deliver results to caller.
+ if !handleDirent(dirent.Ino, dirent.Off, dirent.Type, name) {
+ return
+ }
+
+ // Advance buf for the next dirent.
+ buf = buf[dirent.Reclen:]
+ }
+}