Eliminated redundant checking for unknown ops.

The user must already have this checking, so we don't need it. Getting rid of
it will allow us to call beginOp before calling Convert, necessary for putting
aditional state keeping in that method.
geesefs-0-30-9
Aaron Jacobs 2015-05-05 10:33:49 +10:00
commit 2cbbc756df
3 changed files with 24 additions and 14 deletions

View File

@ -127,7 +127,7 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
continue continue
} }
// Convert it, if possible. // Convert it.
logForOp := func(calldepth int, format string, v ...interface{}) { logForOp := func(calldepth int, format string, v ...interface{}) {
c.log(opID, calldepth+1, format, v...) c.log(opID, calldepth+1, format, v...)
} }
@ -135,12 +135,6 @@ func (c *Connection) ReadOp() (op fuseops.Op, err error) {
finished := func(err error) { c.finishOp() } finished := func(err error) { c.finishOp() }
op = fuseops.Convert(c.parentCtx, bfReq, logForOp, finished) op = fuseops.Convert(c.parentCtx, bfReq, logForOp, finished)
if op == nil {
c.log(opID, 1, "-> ENOSYS: %v", bfReq)
bfReq.RespondError(ENOSYS)
continue
}
c.beginOp() c.beginOp()
return return
} }

View File

@ -25,9 +25,12 @@ import (
// This function is an implementation detail of the fuse package, and must not // This function is an implementation detail of the fuse package, and must not
// be called by anyone else. // be called by anyone else.
// //
// Convert the supplied bazilfuse request struct to an Op, returning nil if it // Convert the supplied bazilfuse request struct to an Op. finished will be
// is unknown. finished will be called with the error supplied to o.Respond // called with the error supplied to o.Respond when the user invokes that
// when the user invokes that method. // method.
//
// It is guaranteed that o != nil. If the op is unknown, a special unexported
// type will be used.
func Convert( func Convert(
opCtx context.Context, opCtx context.Context,
r bazilfuse.Request, r bazilfuse.Request,
@ -213,7 +216,9 @@ func Convert(
co = &to.commonOp co = &to.commonOp
default: default:
return to := &unknownOp{}
io = to
co = &to.commonOp
} }
co.init(opCtx, io, r, logForOp, finished) co.init(opCtx, io, r, logForOp, finished)

View File

@ -40,10 +40,11 @@ type Op interface {
Context() context.Context Context() context.Context
// Repond to the operation with the supplied error. If there is no error, set // Repond to the operation with the supplied error. If there is no error, set
// any necessary output fields and then call Respond(nil). // any necessary output fields and then call Respond(nil). The user must not
// call with a nil error for unrecognized ops; instead, use ENOSYS.
// //
// Once this is invoked, you must exclude any further calls to any method of // Once this is invoked, the user must exclude any further calls to any
// this op. // method of this op.
Respond(error) Respond(error)
// Log information tied to this operation, with semantics equivalent to // Log information tied to this operation, with semantics equivalent to
@ -833,3 +834,13 @@ type ReleaseFileHandleOp struct {
func (o *ReleaseFileHandleOp) toBazilfuseResponse() (bfResp interface{}) { func (o *ReleaseFileHandleOp) toBazilfuseResponse() (bfResp interface{}) {
return return
} }
// A sentinel used for unknown ops. The user is expected to respond with a
// non-nil error.
type unknownOp struct {
commonOp
}
func (o *unknownOp) toBazilfuseResponse() (bfResp interface{}) {
panic(fmt.Sprintf("Should never get here for unknown op: %s", o.ShortDesc()))
}