Ejemplo n.º 1
0
func (s *Session) handleTwalk(cx context.Context, msg styxproto.Twalk, file file) bool {
	newfid := msg.Newfid()

	// Cannot use "opened" (ready for IO) fids for walking; see walk(5)
	// in 9P manual. However, 9pfuse does this, so we'll allow it.
	//if file.rwc != nil {
	//	s.conn.Rerror(msg.Tag(), "walk on opened fid")
	//	s.conn.Flush()
	//	return true
	//}

	// newfid must be unused or equal to fid
	if newfid != msg.Fid() {
		if _, ok := s.conn.sessionFid.Get(newfid); ok {
			s.conn.clearTag(msg.Tag())
			s.conn.Rerror(msg.Tag(), "Twalk: fid %x already in use", newfid)
			s.conn.Flush()
			return true
		}
	}

	// NOTE(droyo) The clone usage of Twalk is hidden from the user
	// of the styx package; we assume that all clients who have procured
	// a fid for a file are permitted to clone that fid, and may do so without
	// side effects.
	if msg.Nwname() == 0 {
		if newfid != msg.Fid() {
			s.files.Put(newfid, file)
			s.conn.sessionFid.Put(newfid, s)
			s.IncRef()
		}
		s.conn.clearTag(msg.Tag())
		s.conn.Rwalk(msg.Tag())
		s.conn.Flush()
		return true
	}

	// see walk.go for more details
	elem := make([]string, 0, msg.Nwname())
	for i := 0; i < cap(elem); i++ {
		elem = append(elem, string(msg.Wname(i)))
	}
	walker := newWalker(s, cx, msg, file.name, elem...)

	for i := range elem {
		fullpath := path.Join(file.name, strings.Join(elem[:i+1], "/"))
		s.requests <- Twalk{
			index:   i,
			walk:    walker,
			reqInfo: newReqInfo(cx, s, msg, fullpath),
		}
	}
	return true
}
Ejemplo n.º 2
0
Archivo: walk.go Proyecto: droyo/styx
func newWalker(s *Session, cx context.Context, msg styxproto.Twalk, base string, elem ...string) *walker {
	qids := make([]styxproto.Qid, len(elem))
	found := qids[:0]
	newpath := path.Join(base, strings.Join(elem, "/"))
	w := &walker{
		qids:     qids,
		found:    found,
		filled:   make([]int32, len(elem)),
		complete: make(chan struct{}),
		collect:  make(chan walkElem),
		session:  s,
		newfid:   msg.Newfid(),
		path:     newpath,
		tag:      msg.Tag(),
		cx:       cx,
	}
	go w.run()
	return w
}