Commit 547051cf authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Collapse arrays into one array of operationHandler.

parent 87625729
......@@ -254,74 +254,68 @@ func (me *MountState) Loop(threaded bool) {
}
func (me *MountState) chopMessage(req *request) bool {
func (me *MountState) chopMessage(req *request) *operationHandler {
inHSize := unsafe.Sizeof(InHeader{})
if len(req.inputBuf) < inHSize {
me.Error(os.NewError(fmt.Sprintf("Short read for input header: %v", req.inputBuf)))
return false
return nil
}
req.inHeader = (*InHeader)(unsafe.Pointer(&req.inputBuf[0]))
req.arg = req.inputBuf[inHSize:]
argSize, ok := inputSize(req.inHeader.Opcode)
if !ok {
handler := getHandler(req.inHeader.Opcode)
if handler == nil || handler.Func == nil {
log.Println("Unknown opcode %d (input)", req.inHeader.Opcode)
req.status = ENOSYS
return true
return handler
}
if len(req.arg) < argSize {
if len(req.arg) < handler.InputSize {
log.Println("Short read for %v: %v", req.inHeader.Opcode, req.arg)
req.status = EIO
return true
return handler
}
if argSize > 0 {
if handler.InputSize > 0 {
req.inData = unsafe.Pointer(&req.arg[0])
req.arg = req.arg[argSize:]
req.arg = req.arg[handler.InputSize:]
}
return true
return handler
}
func (me *MountState) handle(req *request) {
defer me.discardRequest(req)
if !me.chopMessage(req) {
handler := me.chopMessage(req)
if handler == nil {
return
}
if req.status == OK {
me.dispatch(req)
me.dispatch(req, handler)
}
// If we try to write OK, nil, we will get
// error: writer: Writev [[16 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0]]
// failed, err: writev: no such file or directory
if req.inHeader.Opcode != FUSE_FORGET {
serialize(req, me.Debug)
serialize(req, handler, me.Debug)
req.preWriteNs = time.Nanoseconds()
me.Write(req)
}
}
func (me *MountState) dispatch(req *request) {
func (me *MountState) dispatch(req *request, handler *operationHandler) {
req.dispatchNs = time.Nanoseconds()
f := lookupOperation(req.inHeader.Opcode)
if f == nil {
msg := fmt.Sprintf("Unsupported OpCode: %d=%v",
req.inHeader.Opcode, operationName(req.inHeader.Opcode))
me.Error(os.NewError(msg))
req.status = ENOSYS
return
}
if me.Debug {
nm := ""
// TODO - reinstate filename printing.
log.Printf("Dispatch: %v, NodeId: %v %s\n",
operationName(req.inHeader.Opcode), req.inHeader.NodeId, nm)
}
f(me, req)
handler.Func(me, req)
}
// Thanks to Andrew Gerrand for this hack.
......@@ -330,13 +324,8 @@ func asSlice(ptr unsafe.Pointer, byteCount int) []byte {
return *(*[]byte)(unsafe.Pointer(h))
}
func serialize(req *request, debug bool) {
dataLength, ok := outputSize(req.inHeader.Opcode)
if !ok {
log.Println("Unknown opcode %d (output)", req.inHeader.Opcode)
req.status = ENOSYS
return
}
func serialize(req *request, handler *operationHandler, debug bool) {
dataLength := handler.OutputSize
if req.outData == nil || req.status != OK {
dataLength = 0
}
......
......@@ -231,138 +231,94 @@ func doRename(state *MountState, req *request) {
////////////////////////////////////////////////////////////////
var operationNames []string
var inputSizes []int
var outputSizes []int
type operationFunc func(*MountState, *request)
type operation func(*MountState, *request)
type operationHandler struct {
Name string
Func operationFunc
InputSize int
OutputSize int
}
var operationFuncs []operation
var operationHandlers []*operationHandler
func operationName(opcode Opcode) string {
if opcode > OPCODE_COUNT {
h := getHandler(opcode)
if h == nil {
return "unknown"
}
return operationNames[opcode]
}
func inputSize(o Opcode) (int, bool) {
return lookupSize(o, inputSizes)
}
func outputSize(o Opcode) (int, bool) {
return lookupSize(o, outputSizes)
return h.Name
}
func lookupSize(o Opcode, sMap []int) (int, bool) {
func getHandler(o Opcode) *operationHandler {
if o >= OPCODE_COUNT {
return -1, false
}
return sMap[int(o)], true
}
func lookupOperation(o Opcode) operation {
return operationFuncs[o]
}
func makeSizes(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 nil
}
return out
return operationHandlers[o]
}
func init() {
inputSizes = makeSizes(map[int]int{
FUSE_LOOKUP: 0,
operationHandlers = make([]*operationHandler, OPCODE_COUNT)
for i, _ := range operationHandlers {
operationHandlers[i] = &operationHandler{Name: "UNKNOWN"}
}
for op, sz := range map[int]int{
FUSE_FORGET: unsafe.Sizeof(ForgetIn{}),
FUSE_GETATTR: unsafe.Sizeof(GetAttrIn{}),
FUSE_SETATTR: unsafe.Sizeof(SetAttrIn{}),
FUSE_READLINK: 0,
FUSE_SYMLINK: 0,
FUSE_MKNOD: unsafe.Sizeof(MknodIn{}),
FUSE_MKDIR: unsafe.Sizeof(MkdirIn{}),
FUSE_UNLINK: 0,
FUSE_RMDIR: 0,
FUSE_RENAME: unsafe.Sizeof(RenameIn{}),
FUSE_LINK: unsafe.Sizeof(LinkIn{}),
FUSE_OPEN: unsafe.Sizeof(OpenIn{}),
FUSE_READ: unsafe.Sizeof(ReadIn{}),
FUSE_WRITE: unsafe.Sizeof(WriteIn{}),
FUSE_STATFS: 0,
FUSE_RELEASE: unsafe.Sizeof(ReleaseIn{}),
FUSE_FSYNC: unsafe.Sizeof(FsyncIn{}),
FUSE_SETXATTR: unsafe.Sizeof(SetXAttrIn{}),
FUSE_GETXATTR: unsafe.Sizeof(GetXAttrIn{}),
FUSE_LISTXATTR: unsafe.Sizeof(GetXAttrIn{}),
FUSE_REMOVEXATTR: 0,
FUSE_FLUSH: unsafe.Sizeof(FlushIn{}),
FUSE_INIT: unsafe.Sizeof(InitIn{}),
FUSE_OPENDIR: unsafe.Sizeof(OpenIn{}),
FUSE_READDIR: unsafe.Sizeof(ReadIn{}),
FUSE_RELEASEDIR: unsafe.Sizeof(ReleaseIn{}),
FUSE_FSYNCDIR: unsafe.Sizeof(FsyncIn{}),
FUSE_GETLK: 0,
FUSE_SETLK: 0,
FUSE_SETLKW: 0,
FUSE_ACCESS: unsafe.Sizeof(AccessIn{}),
FUSE_CREATE: unsafe.Sizeof(CreateIn{}),
FUSE_INTERRUPT: unsafe.Sizeof(InterruptIn{}),
FUSE_BMAP: unsafe.Sizeof(BmapIn{}),
FUSE_DESTROY: 0,
FUSE_IOCTL: unsafe.Sizeof(IoctlIn{}),
FUSE_POLL: unsafe.Sizeof(PollIn{}),
})
} {
operationHandlers[op].InputSize = sz
}
outputSizes = makeSizes(map[int]int{
for op, sz := range map[int]int{
FUSE_LOOKUP: unsafe.Sizeof(EntryOut{}),
FUSE_FORGET: 0,
FUSE_GETATTR: unsafe.Sizeof(AttrOut{}),
FUSE_SETATTR: unsafe.Sizeof(AttrOut{}),
FUSE_READLINK: 0,
FUSE_SYMLINK: unsafe.Sizeof(EntryOut{}),
FUSE_MKNOD: unsafe.Sizeof(EntryOut{}),
FUSE_MKDIR: unsafe.Sizeof(EntryOut{}),
FUSE_UNLINK: 0,
FUSE_RMDIR: 0,
FUSE_RENAME: 0,
FUSE_LINK: unsafe.Sizeof(EntryOut{}),
FUSE_OPEN: unsafe.Sizeof(OpenOut{}),
FUSE_READ: 0,
FUSE_WRITE: unsafe.Sizeof(WriteOut{}),
FUSE_STATFS: unsafe.Sizeof(StatfsOut{}),
FUSE_RELEASE: 0,
FUSE_FSYNC: 0,
FUSE_SETXATTR: 0,
FUSE_GETXATTR: unsafe.Sizeof(GetXAttrOut{}),
FUSE_LISTXATTR: unsafe.Sizeof(GetXAttrOut{}),
FUSE_REMOVEXATTR: 0,
FUSE_FLUSH: 0,
FUSE_INIT: unsafe.Sizeof(InitOut{}),
FUSE_OPENDIR: unsafe.Sizeof(OpenOut{}),
FUSE_READDIR: 0,
FUSE_RELEASEDIR: 0,
FUSE_FSYNCDIR: 0,
// TODO
FUSE_GETLK: 0,
FUSE_SETLK: 0,
FUSE_SETLKW: 0,
FUSE_ACCESS: 0,
FUSE_CREATE: unsafe.Sizeof(CreateOut{}),
FUSE_INTERRUPT: 0,
FUSE_BMAP: unsafe.Sizeof(BmapOut{}),
FUSE_DESTROY: 0,
FUSE_IOCTL: unsafe.Sizeof(IoctlOut{}),
FUSE_POLL: unsafe.Sizeof(PollOut{}),
})
operationNames = make([]string, OPCODE_COUNT)
for k, v := range map[int]string{
} {
operationHandlers[op].OutputSize = sz
}
for op, v := range map[int]string{
FUSE_LOOKUP: "FUSE_LOOKUP",
FUSE_FORGET: "FUSE_FORGET",
FUSE_GETATTR: "FUSE_GETATTR",
......@@ -401,11 +357,10 @@ func init() {
FUSE_DESTROY: "FUSE_DESTROY",
FUSE_IOCTL: "FUSE_IOCTL",
FUSE_POLL: "FUSE_POLL"} {
operationNames[k] = v
operationHandlers[op].Name = v
}
operationFuncs = make([]operation, OPCODE_COUNT)
for k, v := range map[Opcode]operation{
for op, v := range map[Opcode]operationFunc{
FUSE_OPEN: doOpen,
FUSE_READDIR: doReadDir,
FUSE_WRITE: doWrite,
......@@ -437,6 +392,6 @@ func init() {
FUSE_SYMLINK: doSymlink,
FUSE_RENAME: doRename,
} {
operationFuncs[k] = v
operationHandlers[op].Func = v
}
}
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