Example #1
0
// 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
}
Example #2
0
func (t *Fs) Put(rid string, d zx.Dir, off int64, dc <-chan []byte, pred string) chan zx.Dir {
	d = d.Dup()
	t.dprintf("put %s %v %d '%s'\n", rid, d, off, pred)
	cs := t.IOstats.NewCall(zx.Sput)
	c := make(chan zx.Dir, 1)
	go func() {
		cs.Sending()
		rid, err := zx.AbsPath(rid)
		var nm, n int64
		var nd zx.Dir
		if err == nil && rid == "/Ctl" {
			nc, xerr := t.putCtl(dc)
			if xerr == nil {
				nd = zx.Dir{"size": "0"}
				if DoSum {
					nd["Sum"] = zx.Zsum()
				}
				nd.SetTime("mtime", time.Now())
				nm = 1
				n = int64(nc)
			}
			err = xerr
		} else if err == nil {
			nd, nm, n, err = t.put(rid, d, off, dc, pred)
			cs.Sends(nm, n)
		}
		if err == nil {
			rd := zx.Dir{"size": nd["size"], "mtime": nd["mtime"]}
			if nd["Sum"] != "" {
				rd["Sum"] = nd["Sum"]
			}
			t.dprintf("put %s: %s (wrote %d)\n", rid, rd, n)
			c <- rd
		} else {
			t.dprintf("put %s: %s\n", rid, err)
			close(dc, err)
		}
		close(c, err)
		cs.End(err != nil)
	}()
	return c
}
Example #3
0
func (t *Fs) Put(rid string, d zx.Dir, off int64, dc <-chan []byte, pred string) chan zx.Dir {
	d = d.UsrAttrs()
	t.dprintf("put %s %v %d '%s'\n", rid, d, off, pred)
	cs := t.IOstats.NewCall(zx.Sput)
	c := make(chan zx.Dir, 1)
	go func() {
		cs.Sending()
		rid, err := zx.AbsPath(rid)
		var nd zx.Dir
		if err == nil && rid == "/" {
			err = fmt.Errorf("/: %s", dbg.ErrPerm)
		}
		if err == nil && rid == "/Ctl" {
			xerr := t.putCtl(dc)
			if xerr == nil {
				nd = zx.Dir{"size": "0", "Sum": zx.Zsum()}
				nd.SetTime("mtime", time.Now())
			}
			err = xerr
		} else if err == nil {
			err = t.put(rid, d, off, dc, pred)
			if err == nil {
				nd, err = t.stat(rid)
			}
		}
		if err == nil {
			rd := zx.Dir{"size": nd["size"], "mtime": nd["mtime"], "Sum": nd["Sum"]}
			t.dprintf("put %s: %s\n", rid, rd)
			c <- rd
		} else {
			t.dprintf("put %s: %s\n", rid, err)
			close(dc, err)
		}
		close(c, err)
		cs.End(err != nil)
	}()
	return c
}
Example #4
0
// set a fake mtime that can be predicted.
func TouchZX(fs zx.RWTree, path string) error {
	d := zx.Dir{}
	d.SetTime("mtime", time.Unix(xt/1e9, xt%1e9))
	xt += 1e9
	return <-fs.Wstat(path, d)
}