Commit 919f45da authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Use arrays for opcode dispatches; work in progress.

parent 88b3aa85
This diff is collapsed.
...@@ -13,7 +13,7 @@ func (code Status) String() string { ...@@ -13,7 +13,7 @@ func (code Status) String() string {
return fmt.Sprintf("%d=%v", int(code), os.Errno(code)) return fmt.Sprintf("%d=%v", int(code), os.Errno(code))
} }
func replyString(opcode uint32, ptr unsafe.Pointer) string { func replyString(opcode Opcode, ptr unsafe.Pointer) string {
var val interface{} var val interface{}
switch opcode { switch opcode {
case FUSE_LOOKUP: case FUSE_LOOKUP:
...@@ -27,95 +27,153 @@ func replyString(opcode uint32, ptr unsafe.Pointer) string { ...@@ -27,95 +27,153 @@ func replyString(opcode uint32, ptr unsafe.Pointer) string {
return "" return ""
} }
func operationName(opcode uint32) string { ////////////////////////////////////////////////////////////////
switch opcode {
case FUSE_LOOKUP: func doOpen(state *MountState, req *request) {
return "FUSE_LOOKUP" flags, handle, status := state.fileSystem.Open(req.inHeader, (*OpenIn)(req.inData))
case FUSE_FORGET: req.status = status
return "FUSE_FORGET" if status != OK {
case FUSE_GETATTR: return
return "FUSE_GETATTR" }
case FUSE_SETATTR:
return "FUSE_SETATTR" out := &OpenOut{
case FUSE_READLINK: Fh: handle,
return "FUSE_READLINK" OpenFlags: flags,
case FUSE_SYMLINK: }
return "FUSE_SYMLINK"
case FUSE_MKNOD: req.data = unsafe.Pointer(out)
return "FUSE_MKNOD" }
case FUSE_MKDIR:
return "FUSE_MKDIR"
case FUSE_UNLINK: func doCreate(state *MountState, req *request) {
return "FUSE_UNLINK" flags, handle, entry, status := state.fileSystem.Create(req.inHeader, (*CreateIn)(req.inData), req.filename())
case FUSE_RMDIR: req.status = status
return "FUSE_RMDIR" if status == OK {
case FUSE_RENAME: req.data = unsafe.Pointer(&CreateOut{
return "FUSE_RENAME" EntryOut: *entry,
case FUSE_LINK: OpenOut: OpenOut{
return "FUSE_LINK" Fh: handle,
case FUSE_OPEN: OpenFlags: flags,
return "FUSE_OPEN" },
case FUSE_READ: })
return "FUSE_READ" }
case FUSE_WRITE: }
return "FUSE_WRITE"
case FUSE_STATFS:
return "FUSE_STATFS" func doReadDir(state *MountState, req *request) {
case FUSE_RELEASE: entries, code := state.fileSystem.ReadDir(req.inHeader, (*ReadIn)(req.inData))
return "FUSE_RELEASE" if entries != nil {
case FUSE_FSYNC: req.flatData = entries.Bytes()
return "FUSE_FSYNC" }
case FUSE_SETXATTR: req.status = code
return "FUSE_SETXATTR" }
case FUSE_GETXATTR:
return "FUSE_GETXATTR"
case FUSE_LISTXATTR: func doOpenDir(state *MountState, req *request) {
return "FUSE_LISTXATTR" flags, handle, status := state.fileSystem.OpenDir(req.inHeader, (*OpenIn)(req.inData))
case FUSE_REMOVEXATTR: req.status = status
return "FUSE_REMOVEXATTR" if status == OK {
case FUSE_FLUSH: req.data = unsafe.Pointer(&OpenOut{
return "FUSE_FLUSH" Fh: handle,
case FUSE_INIT: OpenFlags: flags,
return "FUSE_INIT" })
case FUSE_OPENDIR: }
return "FUSE_OPENDIR" }
case FUSE_READDIR:
return "FUSE_READDIR" func doSetattr(state *MountState, req *request) {
case FUSE_RELEASEDIR: // TODO - if Fh != 0, we should do a FSetAttr instead.
return "FUSE_RELEASEDIR" o, s := state.fileSystem.SetAttr(req.inHeader, (*SetAttrIn)(req.inData))
case FUSE_FSYNCDIR: req.data = unsafe.Pointer(o)
return "FUSE_FSYNCDIR" req.status = s
case FUSE_GETLK: }
return "FUSE_GETLK"
case FUSE_SETLK: func doWrite(state *MountState, req *request) {
return "FUSE_SETLK" n, status := state.fileSystem.Write((*WriteIn)(req.inData), req.arg)
case FUSE_SETLKW: o := &WriteOut{
return "FUSE_SETLKW" Size: n,
case FUSE_ACCESS: }
return "FUSE_ACCESS" req.data = unsafe.Pointer(o)
case FUSE_CREATE: req.status = status
return "FUSE_CREATE" }
case FUSE_INTERRUPT:
return "FUSE_INTERRUPT"
case FUSE_BMAP: func doGetXAttr(state *MountState, req *request) {
return "FUSE_BMAP" input := (*GetXAttrIn)(req.inData)
case FUSE_DESTROY: var data []byte
return "FUSE_DESTROY" if req.inHeader.Opcode == FUSE_GETXATTR {
case FUSE_IOCTL: data, req.status = state.fileSystem.GetXAttr(req.inHeader, req.filename())
return "FUSE_IOCTL" } else {
case FUSE_POLL: data, req.status = state.fileSystem.ListXAttr(req.inHeader)
return "FUSE_POLL" }
}
return "UNKNOWN" if req.status != OK {
} return
}
size := uint32(len(data))
var inputSizeMap map[int]int if input.Size == 0 {
var outputSizeMap map[int]int out := &GetXAttrOut{
Size: size,
}
req.data = unsafe.Pointer(out)
}
if size > input.Size {
req.status = ERANGE
}
req.flatData = data
}
////////////////////////////////////////////////////////////////
var operationNames []string
var inputSizeMap []int
var outputSizeMap []int
type operation func(*MountState, *request)
var operationFuncs []operation
func operationName(opcode Opcode) string {
if opcode > OPCODE_COUNT {
return "unknown"
}
return operationNames[opcode]
}
func inputSize(o Opcode) (int, bool) {
return lookupSize(o, inputSizeMap)
}
func outputSize(o Opcode) (int, bool) {
return lookupSize(o, outputSizeMap)
}
func lookupSize(o Opcode, sMap []int) (int, bool) {
if o >= OPCODE_COUNT {
return -1, false
}
return sMap[int(o)], true
}
func lookupOperation(o Opcode) operation {
return operationFuncs[o]
}
func makeSizeMap(dict map[int]int) []int {
out := make([]int, OPCODE_COUNT)
for i, _ := range out {
out[i] = -1
}
for code, val := range dict {
out[code] = val
}
return out
}
func init() { func init() {
inputSizeMap = map[int]int{ inputSizeMap = makeSizeMap(map[int]int{
FUSE_LOOKUP: 0, FUSE_LOOKUP: 0,
FUSE_FORGET: unsafe.Sizeof(ForgetIn{}), FUSE_FORGET: unsafe.Sizeof(ForgetIn{}),
FUSE_GETATTR: unsafe.Sizeof(GetAttrIn{}), FUSE_GETATTR: unsafe.Sizeof(GetAttrIn{}),
...@@ -154,9 +212,9 @@ func init() { ...@@ -154,9 +212,9 @@ func init() {
FUSE_DESTROY: 0, FUSE_DESTROY: 0,
FUSE_IOCTL: unsafe.Sizeof(IoctlIn{}), FUSE_IOCTL: unsafe.Sizeof(IoctlIn{}),
FUSE_POLL: unsafe.Sizeof(PollIn{}), FUSE_POLL: unsafe.Sizeof(PollIn{}),
} })
outputSizeMap = map[int]int{ outputSizeMap = makeSizeMap(map[int]int{
FUSE_LOOKUP: unsafe.Sizeof(EntryOut{}), FUSE_LOOKUP: unsafe.Sizeof(EntryOut{}),
FUSE_FORGET: 0, FUSE_FORGET: 0,
FUSE_GETATTR: unsafe.Sizeof(AttrOut{}), FUSE_GETATTR: unsafe.Sizeof(AttrOut{}),
...@@ -196,5 +254,62 @@ func init() { ...@@ -196,5 +254,62 @@ func init() {
FUSE_DESTROY: 0, FUSE_DESTROY: 0,
FUSE_IOCTL: unsafe.Sizeof(IoctlOut{}), FUSE_IOCTL: unsafe.Sizeof(IoctlOut{}),
FUSE_POLL: unsafe.Sizeof(PollOut{}), FUSE_POLL: unsafe.Sizeof(PollOut{}),
})
operationNames = make([]string, OPCODE_COUNT)
for k, v := range map[int]string{
FUSE_LOOKUP:"FUSE_LOOKUP",
FUSE_FORGET:"FUSE_FORGET",
FUSE_GETATTR:"FUSE_GETATTR",
FUSE_SETATTR:"FUSE_SETATTR",
FUSE_READLINK:"FUSE_READLINK",
FUSE_SYMLINK:"FUSE_SYMLINK",
FUSE_MKNOD:"FUSE_MKNOD",
FUSE_MKDIR:"FUSE_MKDIR",
FUSE_UNLINK:"FUSE_UNLINK",
FUSE_RMDIR:"FUSE_RMDIR",
FUSE_RENAME:"FUSE_RENAME",
FUSE_LINK:"FUSE_LINK",
FUSE_OPEN:"FUSE_OPEN",
FUSE_READ:"FUSE_READ",
FUSE_WRITE:"FUSE_WRITE",
FUSE_STATFS:"FUSE_STATFS",
FUSE_RELEASE:"FUSE_RELEASE",
FUSE_FSYNC:"FUSE_FSYNC",
FUSE_SETXATTR:"FUSE_SETXATTR",
FUSE_GETXATTR:"FUSE_GETXATTR",
FUSE_LISTXATTR:"FUSE_LISTXATTR",
FUSE_REMOVEXATTR:"FUSE_REMOVEXATTR",
FUSE_FLUSH:"FUSE_FLUSH",
FUSE_INIT:"FUSE_INIT",
FUSE_OPENDIR:"FUSE_OPENDIR",
FUSE_READDIR:"FUSE_READDIR",
FUSE_RELEASEDIR:"FUSE_RELEASEDIR",
FUSE_FSYNCDIR:"FUSE_FSYNCDIR",
FUSE_GETLK:"FUSE_GETLK",
FUSE_SETLK:"FUSE_SETLK",
FUSE_SETLKW:"FUSE_SETLKW",
FUSE_ACCESS:"FUSE_ACCESS",
FUSE_CREATE:"FUSE_CREATE",
FUSE_INTERRUPT:"FUSE_INTERRUPT",
FUSE_BMAP:"FUSE_BMAP",
FUSE_DESTROY:"FUSE_DESTROY",
FUSE_IOCTL:"FUSE_IOCTL",
FUSE_POLL:"FUSE_POLL"} {
operationNames[k] = v
}
operationFuncs = make([]operation, OPCODE_COUNT)
for k, v := range map[Opcode]operation{
FUSE_OPEN: doOpen,
FUSE_READDIR: doReadDir,
FUSE_WRITE: doWrite,
FUSE_OPENDIR: doOpenDir,
FUSE_CREATE: doCreate,
FUSE_SETATTR: doSetattr,
FUSE_GETXATTR: doGetXAttr,
FUSE_LISTXATTR: doGetXAttr,
} {
operationFuncs[k] = v
} }
} }
...@@ -143,6 +143,8 @@ const ( ...@@ -143,6 +143,8 @@ const (
FUSE_IOCTL = 39 FUSE_IOCTL = 39
FUSE_POLL = 40 FUSE_POLL = 40
OPCODE_COUNT = 41
CUSE_INIT = 4096 CUSE_INIT = 4096
) )
...@@ -287,8 +289,8 @@ type OpenOut struct { ...@@ -287,8 +289,8 @@ type OpenOut struct {
} }
type CreateOut struct { type CreateOut struct {
Entry EntryOut EntryOut
Open OpenOut OpenOut
} }
type ReleaseIn struct { type ReleaseIn struct {
...@@ -456,7 +458,7 @@ type NotifyPollWakeupOut struct { ...@@ -456,7 +458,7 @@ type NotifyPollWakeupOut struct {
type InHeader struct { type InHeader struct {
Length uint32 Length uint32
Opcode uint32 Opcode
Unique uint64 Unique uint64
NodeId uint64 NodeId uint64
Identity Identity
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment