// Print d in DB format func DbFmt(d zx.Dir) string { var b bytes.Buffer fmt.Fprintf(&b, "%-14s", d["path"]) typ := d["type"] if typ == "" { fmt.Fprintf(&b, " -") } else { fmt.Fprintf(&b, " %s", typ) } if d["rm"] != "" { fmt.Fprintf(&b, " GONE") } else { fmt.Fprintf(&b, " 0%o", d.Mode()) } uid := nouid(d["Uid"]) gid := nouid(d["Gid"]) wuid := nouid(d["Wuid"]) fmt.Fprintf(&b, " %-8s %-8s %-8s", uid, gid, wuid) fmt.Fprintf(&b, " %8d", d.Int64("size")) if d["type"] != "d" { fmt.Fprintf(&b, " %d", d.Uint64("mtime")) } if d["err"] != "" { fmt.Fprintf(&b, " %s", d["err"]) } return b.String() }
// NB: Attributes that the user can't set are always ignored. // If the user has no permissioin to set an attribute, that's an error. // Setting an attribute to an empty string removes it. // Uid, Gid, and Wuid can't be removed. // Meta locking done by caller, might lock data on truncations func (f *mFile) wstat(d zx.Dir) error { if len(d) == 0 { return nil } d = d.Dup() sum := "" if f.d["type"] != "d" { if _, ok := d["size"]; ok { sz := d.Int64("size") if sz < 0 { sz = 0 } f.data.Truncate(sz) d["size"] = strconv.FormatInt(sz, 10) if DoSum { sum = f.data.Sum() } } } else { delete(d, "size") } if _, ok := d["mode"]; ok { mode := d.Int("mode")&0777 d["mode"] = "0" + strconv.FormatInt(int64(mode), 8) } if _, ok := d["mtime"]; ok { d.SetTime("mtime", d.Time("mtime")) } if sum != "" { f.d["Sum"] = sum } ud := d.UsrAttrs() if d["Wuid"] != "" { ud["Wuid"] = d["Wuid"] } for k, v := range ud { if v == "" { delete(f.d, k) } else { f.d[k] = v } } return nil }
func dataChanged(d0, d1 zx.Dir) bool { return d0["type"] != d1["type"] || d0.Int64("size") != d1.Int64("size") || d0.Int64("mtime") != d1.Int64("mtime") || d0["Sum"] != "" && d1["Sum"] != "" && d0["Sum"] != d1["Sum"] }
func (t *Fs) put(rid string, d zx.Dir, off int64, dc <-chan []byte, pred string) (zx.Dir, int64, int64, error) { noinherit := false if m := d["Mode"]; m != "" { d["mode"] = m delete(d, "Mode") noinherit = true } var pf *mFile f, left, err := t.walk(rid, &pf) if err != nil && !dbg.IsNotExist(err) || len(left) > 1|| d["mode"] == "" && err != nil { return nil, 0, 0, err } pmode := uint64(0755) if pf != nil { pf.mlk.Lock() pmode = pf.d.Mode() pf.mlk.Unlock() } app := false f.mlk.Lock() if err == nil && f.d["type"] == "d" || d["type"] == "d" { err = fmt.Errorf("%s: %s", f, dbg.ErrIsDir) f.mlk.Unlock() return nil, 0, 0, err } if !t.noPerms() && !f.d.CanWrite(t.ai) { err = fmt.Errorf("%s: %s", f, dbg.ErrPerm) f.mlk.Unlock() return nil, 0, 0, err } u := dbg.Usr if t.ai != nil { u = t.ai.Uid } if d == nil { d = zx.Dir{} } ai := t.ai if t.NoPermCheck { ai = nil } if d["mode"] == "" || err == nil { // truncate or rewrite if err := t.matchDir(rid, f.d, pred); err != nil { f.mlk.Unlock() return nil, 0, 0, err } if !t.WstatAll || t.ai != nil { if err := f.d.CanWstat(ai, d); err != nil { f.mlk.Unlock() return nil, 0, 0, err } } } else { if err := t.matchDir(rid, nil, pred); err != nil { f.mlk.Unlock() return nil, 0, 0, err } } if d["mode"] == "" { if off < 0 { off = 0 app = true } if t.WstatAll && t.ai == nil && d["Wuid"] != "" { f.d["Wuid"] = d["Wuid"] } else { f.d["Wuid"] = u } if d["size"] != "" { f.data.Truncate(d.Int64("size")) f.d["size"] = strconv.FormatInt(int64(f.data.Len()), 10) } } else if err == nil { // truncate existing file if !noinherit && (!t.WstatAll || t.ai != nil) { d.Inherit(pmode) } f.data.Truncate(d.Int64("size")) f.d["size"] = strconv.FormatInt(int64(f.data.Len()), 10) if t.WstatAll && t.ai == nil && d["Wuid"] != "" { f.d["Wuid"] = d["Wuid"] } else { f.d["Wuid"] = u } } else { // create a new file nf := &mFile { name: left[0], d: zx.Dir{ "mode": d["mode"], "name": left[0], "path": rid, "spath": rid, "tpath": f.d["tpath"], "Uid": u, "Gid": f.d["Gid"], "Wuid": u, "type": "-", "size": "0", "proto": "proc", }, data: &bufs.Blocks{Mutex: &sync.Mutex{}}, t: t, } if !t.WstatAll || t.ai != nil { if !noinherit { nf.d.Inherit(pmode) d["mode"] = nf.d["mode"] } if err := f.d.CanWstat(ai, d); err != nil { f.mlk.Unlock() return nil, 0, 0, err } } else if d["Wuid"] != "" { f.d["Wuid"] = d["Wuid"] } nf.data.Truncate(d.Int64("size")) nf.d["size"] = strconv.FormatInt(int64(nf.data.Len()), 10) f.clk.Lock() f.attach(nf) f.clk.Unlock() f.mlk.Unlock() f = nf f.mlk.Lock() } if app { off = int64(f.data.Len()) } delete(d, "size") f.wstat(d.UsrAttrs()) f.mlk.Unlock() n, err := f.data.RecvAtFrom(off, dc) f.mlk.Lock() defer f.mlk.Unlock() if DoSum { sum := f.data.Sum() f.d["Sum"] = sum } size := f.data.Len() f.d["size"] = strconv.Itoa(size) if d["mtime"] == "" { f.d.SetTime("mtime", time.Now()) } return f.d.Dup(), 1, int64(n), err }