func Gets(t Fataler, fss ...zx.Tree) { for i := 0; i < Repeats; i++ { for _, fs := range fss { for _, p := range GetFPaths { printf("getall %s\n", p) dat, err := zx.GetAll(fs, p) if err != nil { t.Fatalf("get %s: %s", p, err) } printf("got %d bytes \n\n", len(dat)) if string(dat) != string(FileData[p]) { printf("got <%s>\nexpected<%s>\n", string(dat), string(FileData[p])) t.Fatalf("%s: bad data", p) } } for _, p := range GetDPaths { printf("getall %s\n", p) dat, err := zx.GetAll(fs, p) if err != nil { t.Fatalf("get %s: %s", p, err) } var d zx.Dir ents := []string{} for len(dat) > 0 { d, dat, err = zx.UnpackDir(dat) if err != nil { t.Fatalf("dir: %s", err) } if d["path"] == "/Ctl" || d["path"] == "/Chg" { continue } ents = append(ents, d.TestFmt()) } if strings.Join(GetDOuts[p], "\n") != strings.Join(ents, "\n") { t.Fatalf("bad dir data for %s", p) } printf("got %d ents (ctl, chg excluded)\n", len(ents)) } for _, p := range BadPaths { dat, err := zx.GetAll(fs, p) if err==nil || len(dat)>0 { t.Fatalf("get %s didn't fail", p) } } printf("\n") } } }
// d is a dup and can be changed. func (f *mFile) find(d zx.Dir, p *pred.Pred, spref, dpref string, lvl int, c chan<- zx.Dir, ai *auth.Info) { match, pruned, err := p.EvalAt(d, lvl) f.dprintf("find at %d %s\n\t%v\n\t%v %v %v\n\n", lvl, d.Long(), p, match, pruned, err) if pruned { if !match { d["err"] = "pruned" } c <- d return } if d["type"] == "d" && err == nil { f.mlk.Lock() if !f.t.NoPermCheck && !f.d.CanWalk(ai) { err = dbg.ErrPerm } f.mlk.Unlock() } if err != nil { d["err"] = err.Error() c <-d return } if d["rm"] != "" { return } if match { if ok := c <- d; !ok { return } } if d["type"] != "d" { return } f.clk.Lock() child := make([]*mFile, len(f.child)) copy(child, f.child) f.clk.Unlock() if f.name == "/" { nc := []*mFile{ &mFile{name: "Ctl", d: ctldir.Dup(), t: f.t}, } nc[0].d["tpath"] = f.t.path child = append(nc, child...) } for _, cf := range child { cf.mlk.Lock() cd := cf.d.Dup() cf.mlk.Unlock() // fmt.Printf("child %s\n", cd) if cd["rm"] != "" { continue } if spref != dpref { cpath := cd["path"] suff := zx.Suffix(cpath, spref) cd["path"] = zx.Path(dpref, suff) } cf.find(cd, p, spref, dpref, lvl+1, c, ai) } } func (t *Fs) Find(rid, fpred, spref, dpref string, depth int) <-chan zx.Dir { t.dprintf("find %s '%s' '%s' '%s' %d\n", rid, fpred, spref, dpref, depth) cs := t.IOstats.NewCall(zx.Sfind) dc := make(chan zx.Dir) go func() { rid, err := zx.AbsPath(rid) if err != nil { cs.End(err != nil) t.dprintf("find %s: %s\n", rid, err) close(dc, err) return } f, _, err := t.walk(rid, nil) if err != nil { cs.End(err != nil) t.dprintf("find %s: %s\n", rid, err) close(dc, err) return } p, err := pred.New(fpred) if err != nil { cs.End(err != nil) t.dprintf("find %s: %s\n", rid, err) close(dc, err) return } cs.Sending() f.mlk.Lock() d := f.d.Dup() f.mlk.Unlock() if spref != dpref { suff := zx.Suffix(rid, spref) d["path"] = zx.Path(dpref, suff) } f.find(d, p, spref, dpref, depth, dc, t.ai) cs.End(err != nil) t.dprintf("find %s: ok\n", rid) close(dc) }() return dc } func (t *Fs) FindGet(rid, fpred, spref, dpref string, depth int) <-chan zx.DirData { t.dprintf("findget %s '%s' '%s' '%s' %d\n", rid, fpred, spref, dpref, depth) gc := make(chan zx.DirData) cs := t.IOstats.NewCall(zx.Sfindget) go func() { dc := t.Find(rid, fpred, spref, dpref, depth) // BUG: will stat a Sfind for d := range dc { g := zx.DirData{Dir: d} var datac chan []byte if d["err"]=="" && d["type"]=="-" { datac = make(chan []byte) g.Datac = datac } if ok := gc <- g; !ok { close(dc, cerror(gc)) break } if datac != nil { err := t.get(d["spath"], 0, zx.All, datac, nil) close(datac, err) } } err := cerror(dc) cs.End(err != nil) if err != nil { t.dprintf("find %s: %s\n", rid, err) } else { t.dprintf("find %s: ok\n", rid) } close(gc, err) }() return gc } func (t *Fs) Dump(w io.Writer) { if t == nil { fmt.Fprintf(w, "<nil tree>\n") return } fmt.Fprintf(w, "tree [%s] path %s\n", t.name, t.path) t.root.Dump(w, 0) fmt.Fprintf(w, "\n") } func (f *mFile) Dump(w io.Writer, lvl int) { tabs := strings.Repeat(" ", lvl) if f == nil { fmt.Fprintf(w, "%s<nil file>\n", tabs) return } d := f.d.Dup() if d["path"] == "/" { d["size"] = "0" } fmt.Fprintf(w, "%s%s\n", tabs, d.TestFmt()) if d["type"] != "d" { fmt.Fprintf(w, "%s %d bytes\n", tabs, f.data.Len()) return } for _, c := range f.child { c.Dump(w, lvl+1) } }