Example #1
0
func New(t zx.Tree) *Fs {
	fs := &Fs{
		ufs: t,
		fs: zx.RWTreeFor(t),
		Flags: &Flags{},
	}
	return fs
}
Example #2
0
// Resolve a name and return the prefix, the zx.RWTrees for it and the server paths
// for each one. If the trees are read-only, null write methods are supplied
// using a zx.Partial tree.
// If there are errors, the last one is reproted and any partial results are returned.
// The path must be absolute.
func (ns *Tree) ResolveTree(name string) (pref string, ts []zx.RWTree, spaths []string, err error) {
	ppath, mnts, paths, err := ns.Resolve(name)
	if err != nil {
		return "", nil, nil, err
	}
	ts = make([]zx.RWTree, 0, len(mnts))
	spaths = make([]string, 0, len(paths))
	for i, d := range mnts {
		t, terr := zx.RWDirTree(d)
		if err != nil {
			err = terr
		} else {
			ts = append(ts, zx.RWTreeFor(t))
			spaths = append(spaths, paths[i])
		}
	}
	if len(ts) == 0 && err == nil {
		err = errors.New("no mounted tree")
	}
	return ppath, ts, spaths, err
}
Example #3
0
func (t *Fs) Get(rid string, off, count int64, pred string) <-chan []byte {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->get[%d] %s %d %d '%s'", n, rid, off, count, pred)
	dc := make(chan []byte)
	go func(){
		xc := t.fs.Get(rid, off, count, pred)
		nb, nm := 0, 0
		for d := range xc {
			s := dbg.HexStr(d, 16)
			t.vprintf("<-get[%d] %d bytes %s", n, len(d), s)
			if ok := dc <- d; !ok {
				close(xc, "client gone")
			}
			nb += len(d)
			nm++
		}
		err := cerror(xc)
		t.printf("<-get[%d] %d bytes %d msgs sts %v", n, nb, nm, err)
		close(dc, err)
	}()
	return dc
}

func (t *Fs) Put(rid string, d zx.Dir, off int64, dc <-chan []byte, pred string) chan zx.Dir {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->put[%d] %s %s %d '%s'", n, rid, d, off, pred)
	rc := make(chan zx.Dir, 1)
	datc := make(chan []byte)
	if dc == nil {
		datc = nil
	} else {
		go func() {
			for d := range dc {
				s := dbg.HexStr(d, 16)
				t.vprintf("->put[%d] %d bytes %s", n, len(d), s)
				if ok := datc <- d; !ok {
					close(dc, cerror(datc))
					break
				}
			}
			err := cerror(dc)
			t.vprintf("->put[%d] sts %v", n, err)
			close(datc, err)
		}()
	}
	go func() {
		xc := t.fs.Put(rid, d, off, datc, pred)
		d := <-xc
		err := cerror(xc)
		if err != nil {
			close(datc, err)
		}
		t.printf("<-put[%d] %s sts %v", n, d, err)
		rc <-d
		close(rc, err)
	}()
	return rc
}

func (t *Fs) Mkdir(rid string, d zx.Dir) chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->mkdir[%d] %s %s", n, rid, d)
	dc := make(chan error, 1)
	go func() {
		xc := t.fs.Mkdir(rid, d)
		err := <- xc
		t.printf("<-mkdir[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) Wstat(rid string, d zx.Dir) chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->wstat[%d] %s %s", n, rid, d)
	dc := make(chan error, 1)
	go func() {
		xc := t.fs.Wstat(rid, d)
		err := <- xc
		t.printf("<-wstat[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) Move(from, to string) chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->move[%d] %s %s", n, from, to)
	dc := make(chan error, 1)
	go func() {
		xc := t.fs.Move(from, to)
		err := <- xc
		t.printf("<-move[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) Remove(rid string) chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->remove[%d] %s", n, rid)
	dc := make(chan error, 1)
	go func() {
		xc := t.fs.Remove(rid)
		err := <- xc
		t.printf("<-remove[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) RemoveAll(rid string) chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->removeall[%d] %s", n, rid)
	dc := make(chan error, 1)
	go func() {
		xc := t.fs.RemoveAll(rid)
		err := <- xc
		t.printf("<-removeall[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) Fsys(name string) <-chan error {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->fsys[%d] %s", n, name)
	dc := make(chan error, 1)
	go func() {
		var xc <-chan error
		if fnd, ok := t.fs.(zx.Finder); ok {
			xc = fnd.Fsys(name)
		} else {
			xx := make(chan error, 1)
			xx <- dbg.ErrBug
			close(xx, dbg.ErrBug)
			xc = xx
		}
		err := <- xc
		t.printf("<-fsys[%d] sts %v", n, err)
		dc <- err
		close(dc, cerror(xc))
	}()
	return dc
}

func (t *Fs) Find(rid, fpred, spref, dpref string, depth int) <-chan zx.Dir {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->find[%d] %s '%s' '%s' '%s' %d", n, rid, fpred, spref, dpref, depth)
	dc := make(chan zx.Dir, 1)
	go func() {
		xc := t.fs.Find(rid, fpred, spref, dpref, depth)
		nm := 0
		for d := range xc {
			nm++
			t.vprintf("<-find[%d] %s", n, d)
			dc <- d
		}
		err := cerror(xc)
		t.printf("<-find[%d] %d msgs sts %v", n, nm, err)
		close(dc, err)
	}()
	return dc
}

func (t *Fs) FindGet(rid, fpred, spref, dpref string, depth int) <-chan zx.DirData {
	n := atomic.AddInt32(&t.nb, 1)
	t.printf("->findget[%d] %s '%s' '%s' '%s' %d", n, rid, fpred, spref, dpref, depth)
	dc := make(chan zx.DirData)
	go func() {
		xc := t.fs.FindGet(rid, fpred, spref, dpref, depth)
		nm := 0
		for d := range xc {
			nm++
			t.vprintf("<-findget[%d] %s", n, d)
			if ok := dc <- d; !ok {
				close(xc, "client gone")
			}
		}
		err := cerror(xc)
		t.printf("<-findget[%d] %d msgs sts %v", n, nm, err)
		close(dc, err)
	}()
	return dc
}

// Ask the tree to perform auth checks on behalf of ai.
func (t *Fs) AuthFor(ai *auth.Info) (zx.Tree, error) {
	nfs := &Fs{}
	*nfs = *t
	if afs, ok := t.ufs.(zx.AuthTree); ok {
		x, err := afs.AuthFor(ai)
		if err == nil {
			nfs.ufs = x
			nfs.fs = zx.RWTreeFor(nfs.ufs)
			return nfs, nil
		}
		return nil, err
	}
	return nil, errors.New("no auth")
}

func (t *Fs) Dump(w io.Writer) {
	if dfs, ok := t.fs.(zx.Dumper); ok {
		dfs.Dump(w)
	} else {
		fmt.Fprintf(w, "no dumps for %s\n", t)
	}
}

func (t *Fs) Stats() *zx.IOstats {
	if dfs, ok := t.fs.(zx.StatTree); ok {
		return dfs.Stats()
	}
	return nil
}