func mkdirNormalMasterRun(master *Master, arg string, rep *WorkResponse) { rootless := strings.TrimLeft(arg, "/") dir, _ := SplitPath(rootless) dirAttr := master.fileServer.attributes.Get(dir) if dirAttr.Deletion() { rep.Stderr = fmt.Sprintf("File not found: /%s", dir) rep.Exit = syscall.WaitStatus(1 << 8) return } if !dirAttr.IsDir() { rep.Stderr = fmt.Sprintf("Is not a directory: /%s", dir) rep.Exit = syscall.WaitStatus(1 << 8) return } chAttr := master.fileServer.attributes.Get(rootless) if !chAttr.Deletion() { rep.Stderr = fmt.Sprintf("File exists: /%s", rootless) rep.Exit = syscall.WaitStatus(1 << 8) return } chAttr = mkdirEntry(rootless) fs := attr.FileSet{} ct := chAttr.ChangeTime() mt := chAttr.ModTime() dirAttr.SetTimes(nil, &mt, &ct) fs.Files = append(fs.Files, dirAttr, chAttr) master.replay(fs) }
// fillReply empties the unionFs and hashes files as needed. It will // return the FS back the pool as soon as possible. func (t *Mirror) fillReply(state *workerFSState) (*attr.FileSet, []string) { fsResult := state.fs.reap() t.returnFS(state) files := make([]*attr.FileAttr, 0, len(fsResult.files)) wrRoot := strings.TrimLeft(state.fs.fuseFS.writableRoot, "/") reapedHashes := map[string]string{} for path, v := range fsResult.files { f := &attr.FileAttr{ Path: fastpath.Join(wrRoot, path), } if v.Attr != nil { f.Attr = v.Attr } f.Link = v.Link if !f.Deletion() && f.IsRegular() { contentPath := fastpath.Join(wrRoot, v.Original) if v.Original != "" && v.Original != contentPath { fa := t.rpcFs.attr.Get(contentPath) if fa.Hash == "" { log.Panicf("Contents for %q disappeared.", contentPath) } f.Hash = fa.Hash } if v.Backing != "" { h, ok := reapedHashes[v.Backing] if !ok { var err error h, err = t.worker.content.DestructiveSavePath(v.Backing) if err != nil || h == "" { log.Fatalf("DestructiveSavePath fail %v, %q", err, h) } reapedHashes[v.Backing] = h } f.Hash = h } } files = append(files, f) } fset := attr.FileSet{Files: files} fset.Sort() err := os.Remove(fsResult.dir) if err != nil { log.Fatalf("fillReply: Remove failed: %v", err) } return &fset, fsResult.reads }
func rmMaybeMasterRun(master *Master, req *WorkRequest, rep *WorkResponse) bool { g := Getopt(req.Argv[1:], nil, nil, true) force := g.HasLong("force") || g.HasShort('f') delete(g.Long, "force") delete(g.Short, 'f') recursive := g.HasLong("recursive") || g.HasShort('r') || g.HasShort('R') delete(g.Long, "recursive") delete(g.Short, 'R') delete(g.Short, 'r') if g.HasOptions() { return false } log.Println("Running in master:", req.Summary()) todo := []string{} for _, a := range g.Args { if a[0] != '/' { a = filepath.Join(req.Dir, a) } a = strings.TrimLeft(filepath.Clean(a), "/") todo = append(todo, a) } fs := attr.FileSet{} msgs := []string{} status := 0 now := time.Now() if recursive { for _, t := range todo { parentDir, _ := SplitPath(t) parent := master.attributes.Get(parentDir) if parent.Deletion() { continue } parent.SetTimes(nil, &now, &now) fs.Files = append(fs.Files, parent) for _, n := range recurseNames(master, t) { fs.Files = append(fs.Files, &attr.FileAttr{ Path: n, }) } } } else { for _, p := range todo { a := master.fileServer.attributes.GetDir(p) switch { case a.Deletion(): if !force { msgs = append(msgs, fmt.Sprintf("rm: no such file or directory: %s", p)) status = 1 } case a.IsDir() && !recursive: msgs = append(msgs, fmt.Sprintf("rm: is a directory: %s", p)) status = 1 default: parentDir, _ := SplitPath(p) parentAttr := master.attributes.Get(parentDir) parentAttr.SetTimes(nil, &now, &now) fs.Files = append(fs.Files, parentAttr, &attr.FileAttr{Path: p}) } } } master.replay(fs) rep.Stderr = strings.Join(msgs, "\n") rep.Exit = syscall.WaitStatus(status << 8) return true }