-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsyscall.go
80 lines (71 loc) · 1.8 KB
/
syscall.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package scoutfs
import (
"os"
"syscall"
"unsafe"
)
const (
// sysOpenByHandleAt linux system call
sysOpenByHandleAt = 304
// fileIDScoutfs for scoutfs file handle
fileIDScoutfs = 0x81
)
type fileID struct {
Ino uint64
ParentIno uint64
}
type fileHandle struct {
FidSize uint32
HandleType int32
FID fileID
}
// OpenByHandle is similar to OpenByID, but returns just the file descriptor
// and does not have the added overhead of getting the filename
// An open file within scoutfs is supplied for ioctls
// (usually just the base mount point directory)
func OpenByHandle(dirfd *os.File, ino uint64, flags int) (uintptr, error) {
h := &fileHandle{
FidSize: uint32(unsafe.Sizeof(fileID{})),
HandleType: fileIDScoutfs,
FID: fileID{Ino: ino},
}
return openbyhandleat(dirfd, h, flags)
}
func openbyhandleat(dirfd *os.File, handle *fileHandle, flags int) (uintptr, error) {
fd, _, e1 := syscall.Syscall6(sysOpenByHandleAt, uintptr(dirfd.Fd()), uintptr(unsafe.Pointer(handle)), uintptr(flags), 0, 0, 0)
var err error
if e1 != 0 {
err = errnoErr(e1)
}
return fd, err
}
func scoutfsctl(f *os.File, cmd int, ptr unsafe.Pointer) (int, error) {
count, _, e1 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(f.Fd()), uintptr(cmd), uintptr(ptr))
var err error
if e1 != 0 {
err = errnoErr(e1)
}
return int(count), err
}
// Do the interface allocations only once for common
// Errno values.
var (
errEAGAIN error = syscall.EAGAIN
errEINVAL error = syscall.EINVAL
errENOENT error = syscall.ENOENT
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return nil
case syscall.EAGAIN:
return errEAGAIN
case syscall.EINVAL:
return errEINVAL
case syscall.ENOENT:
return errENOENT
}
return e
}