// 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 }