// locks/unlocks f's data func (f *mFile) getDir(off, count int64, dc chan<- []byte, cs *zx.CallStat) error { f.clk.Lock() ds := make([]*mFile, len(f.child)) copy(ds, f.child) f.clk.Unlock() nd := 0 ctlsent := false Dloop: for i := 0; i < len(ds); { if off > 0 { off-- if !ctlsent && f.name =="/" { ctlsent = true } else { i++ } continue } switch count { case zx.All: break case 0: break Dloop default: count-- } if !ctlsent && f.name=="/" { ctlsent = true nd++ d := ctldir.Dup() d["tpath"] = f.d["tpath"] d.Send(dc) nd++ // but not i++ continue } ds[i].mlk.Lock() d := ds[i].d.Dup() ds[i].mlk.Unlock() cs.Send(0) if _, err := d.Send(dc); err != nil { return err } nd++ i++ } return nil }
func (t *Fs) getCtl(off, count int64, dc chan<- []byte, cs *zx.CallStat) error { var buf bytes.Buffer fmt.Fprintf(&buf, "%s:\n", t.Name()) fmt.Fprintf(&buf, "%s", t.Flags) t.IOstats.Averages() fmt.Fprintf(&buf, "%s\n", t.IOstats.String()) resp := buf.Bytes() o := int(off) if o >= len(resp) { o = len(resp) } resp = resp[o:] n := int(count) if n>len(resp) || n<0 { n = len(resp) } resp = resp[:n] cs.Send(int64(len(resp))) dc <- resp return nil }
func (fs *Cfs) getCtl(off, count int64, pred string, c chan<- []byte, cs *zx.CallStat) (int, error) { var buf bytes.Buffer fmt.Fprintf(&buf, "%s:\n", fs.Name()) users := fs.Users() for _, k := range users { fmt.Fprintf(&buf, "user\t%s\n", k) } fmt.Fprintf(&buf, "%s", fs.Flags) fs.IOstats.Averages() fmt.Fprintf(&buf, "%s\n", fs.IOstats.String()) lctl, _ := zx.GetAll(fs.lfs, "/Ctl") if len(lctl) > 0 { buf.Write(lctl) } rctl, _ := zx.GetAll(fs.rfs, "/Ctl") if len(rctl) > 0 { buf.Write(rctl) } resp := buf.Bytes() o := int(off) if o >= len(resp) { o = len(resp) } resp = resp[o:] n := int(count) if n > len(resp) || n < 0 { n = len(resp) } resp = resp[:n] cs.Send(int64(len(resp))) c <- resp return n, nil }
func (t *Lfs) get(rid string, off, count int64, dc chan<- []byte, cs *zx.CallStat) (int64, error) { rid, err := zx.AbsPath(rid) if err != nil { return 0, err } if rid == "/Ctl" { return t.getCtl(off, count, dc, cs) } path := zx.Path(t.path, rid) fd, err := os.Open(path) if err==nil && t.ai!=nil && !t.NoPermCheck { _, _, err = t.canWalkTo(rid, 0444) } if err != nil { return 0, err } defer fd.Close() st, err := fd.Stat() if err != nil { return 0, err } if off!=0 && !st.IsDir() { if _, err := fd.Seek(off, 0); err != nil { return 0, err } } if st.IsDir() { ds, err := ioutil.ReadDir(path) nd := 0 tot := 0 ctlsent := false var xds map[string]zx.Dir if t.readattrs { xds, _ = t.dirAttrs(path) } Dloop: for i := 0; i < len(ds); { if off > 0 { off-- if !ctlsent && rid=="/" { ctlsent = true } else { i++ } continue } switch count { case zx.All: break case 0: break Dloop default: count-- } if !ctlsent && rid=="/" { ctlsent = true nd++ d := ctldir n, _ := d.Send(dc) nd++ // but not i++ tot += n continue } fi := ds[i] if fi.Name() == afname { if i == len(ds)-1 { break } ds = append(ds[:i], ds[i+1:]...) fi = ds[i] } cpath := zx.Path(path, fi.Name()) n := 0 sum := "" if fi.IsDir() { n, sum = dirsz(cpath) } d := zx.NewDir(fi, n) d["path"] = zx.Path(rid, fi.Name()) d["spath"] = d["path"] d["tpath"] = t.path if t.readattrs { if xd, ok := xds[fi.Name()]; ok { for k, v := range xd { if zx.IsUpper(k) { d[k] = v } } } else { d["Uid"] = dbg.Usr d["Gid"] = dbg.Usr } } if sum != "" { d["Sum"] = sum } cs.Send(0) n, err := d.Send(dc) if err != nil { return int64(tot), err } nd++ i++ tot += n } return int64(tot), err } if count == zx.All { cs.Sending() nm, n, err := nchan.ReadBytesFrom(fd, dc) cs.Sends(nm, n) return n, err } rr := io.LimitReader(fd, count) cs.Sending() nm, n, err := nchan.ReadBytesFrom(rr, dc) cs.Sends(nm, n) return n, err }