6 "golang.org/x/net/context"
9 type handler interface {
10 handle(ctx context.Context, req *Fcall) (*Fcall, error)
13 // dispatcher routes fcalls to a Session.
14 type dispatcher struct {
18 // handle responds to an fcall using the session. An error is only returned if
19 // the handler cannot proceed. All session errors are returned as Rerror.
20 func (d *dispatcher) handle(ctx context.Context, req *Fcall) (*Fcall, error) {
24 reqmsg, ok := req.Message.(MessageTauth)
26 return nil, fmt.Errorf("incorrect message for type: %v message=%v", req, req.Message)
29 qid, err := d.session.Auth(ctx, reqmsg.Afid, reqmsg.Uname, reqmsg.Aname)
34 resp = newFcall(MessageRauth{Qid: qid})
36 reqmsg, ok := req.Message.(*MessageTattach)
38 return nil, fmt.Errorf("bad message: %v message=%#v", req, req.Message)
41 qid, err := d.session.Attach(ctx, reqmsg.Fid, reqmsg.Afid, reqmsg.Uname, reqmsg.Aname)
46 resp = newFcall(MessageRattach{
50 reqmsg, ok := req.Message.(*MessageTwalk)
52 return nil, fmt.Errorf("bad message: %v message=%#v", req, req.Message)
55 // TODO(stevvooe): This is one of the places where we need to manage
56 // fid allocation lifecycle. We need to reserve the fid, then, if this
57 // call succeeds, we should alloc the fid for future uses. Also need
58 // to interact correctly with concurrent clunk and the flush of this
60 qids, err := d.session.Walk(ctx, reqmsg.Fid, reqmsg.Newfid, reqmsg.Wnames...)
65 resp = newFcall(&MessageRwalk{
69 reqmsg, ok := req.Message.(*MessageTopen)
71 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
74 qid, iounit, err := d.session.Open(ctx, reqmsg.Fid, reqmsg.Mode)
79 resp = newFcall(&MessageRopen{
84 reqmsg, ok := req.Message.(*MessageTcreate)
86 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
89 qid, iounit, err := d.session.Create(ctx, reqmsg.Fid, reqmsg.Name, reqmsg.Perm, uint32(reqmsg.Mode))
94 resp = newFcall(&MessageRcreate{
100 reqmsg, ok := req.Message.(*MessageTread)
102 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
105 p := make([]byte, int(reqmsg.Count))
106 n, err := d.session.Read(ctx, reqmsg.Fid, p, int64(reqmsg.Offset))
111 resp = newFcall(&MessageRread{
115 reqmsg, ok := req.Message.(*MessageTwrite)
117 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
120 n, err := d.session.Write(ctx, reqmsg.Fid, reqmsg.Data, int64(reqmsg.Offset))
125 resp = newFcall(&MessageRwrite{
129 reqmsg, ok := req.Message.(*MessageTclunk)
131 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
134 // TODO(stevvooe): Manage the clunking of file descriptors based on
135 // walk and attach call progression.
136 if err := d.session.Clunk(ctx, reqmsg.Fid); err != nil {
140 resp = newFcall(&MessageRclunk{})
142 reqmsg, ok := req.Message.(*MessageTremove)
144 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
147 if err := d.session.Remove(ctx, reqmsg.Fid); err != nil {
151 resp = newFcall(&MessageRremove{})
153 reqmsg, ok := req.Message.(*MessageTstat)
155 return nil, fmt.Errorf("bad message: %v message=%v", req, req.Message)
158 dir, err := d.session.Stat(ctx, reqmsg.Fid)
163 resp = newFcall(&MessageRstat{
167 panic("not implemented")
169 return nil, ErrUnknownMsg