func (c *rawBridge) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOut) (code fuse.Status) { parent := c.toInode(header.NodeId) if !parent.IsDir() { log.Printf("Lookup %q called on non-Directory node %d", name, header.NodeId) return fuse.ENOTDIR } outAttr := (*fuse.Attr)(&out.Attr) child, code := c.fsConn().internalLookup(outAttr, parent, name, header) if code == fuse.ENOENT && parent.mount.negativeEntry(out) { return fuse.OK } if !code.Ok() { return code } if child == nil { log.Println("Lookup returned fuse.OK with nil child", name) } child.mount.fillEntry(out) out.NodeId = c.fsConn().lookupUpdate(child) out.Generation = child.generation out.Ino = out.NodeId return fuse.OK }
func (constor *Constor) ReadDirPlus(input *fuse.ReadIn, fuseout *fuse.DirEntryList) fuse.Status { constor.log("") constor.log("%d", input.Offset) ptr := uintptr(input.Fh) offset := input.Offset entryOut := fuse.EntryOut{} out := (*DirEntryList)(unsafe.Pointer(fuseout)) F := constor.getfd(ptr) stream := F.stream if stream == nil { return fuse.EIO } if offset > uint64(len(stream)) { return fuse.EINVAL } todo := F.stream[offset:] for _, e := range todo { if e.Name == "" { continue } attr := (*fuse.Attr)(&entryOut.Attr) attr.FromStat(&e.Stat) entryOut.NodeId = attr.Ino entryOut.Ino = attr.Ino ok, _ := out.AddDirLookupEntry(e, &entryOut) if !ok { break } } return fuse.OK }
// childLookup fills entry information for a newly created child inode func (c *rawBridge) childLookup(out *fuse.EntryOut, n *Inode, context *fuse.Context) { n.Node().GetAttr((*fuse.Attr)(&out.Attr), nil, context) n.mount.fillEntry(out) out.Ino = c.fsConn().lookupUpdate(n) out.NodeId = out.Ino if out.Nlink == 0 { // With Nlink == 0, newer kernels will refuse link // operations. out.Nlink = 1 } }
func (constor *Constor) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOut) fuse.Status { var stat syscall.Stat_t if len(name) > 255 { constor.error("name too long : %s", name) return fuse.Status(syscall.ENAMETOOLONG) } li := -1 parent := constor.inodemap.findInodePtr(header.NodeId) if parent == nil { constor.error("Unable to find parent inode : %d", header.NodeId) return fuse.ENOENT } constor.log("%s(%s)", parent.id, name) id, err := constor.getid(-1, parent.id, name) if err != nil { // logging this error will produce too many logs as there will be too many // lookps on non-existant files return fuse.ToStatus(err) } inode := constor.inodemap.findInodeId(id) if inode != nil { li = inode.layer } else { li = constor.getLayer(id) } if li == -1 { constor.error("Unable to find inode for %s(%s) id %s", parent.id, name, id) return fuse.ENOENT } err = constor.Lstat(li, id, &stat) if err != nil { constor.error("Unable to Lstat inode for %s(%s) id %s", parent.id, name, id) return fuse.ToStatus(err) } if inode == nil { inode = NewInode(constor, id) inode.layer = li constor.inodemap.hashInode(inode) } else { inode.lookup() } attr := (*fuse.Attr)(&out.Attr) attr.FromStat(&stat) out.NodeId = uint64(uintptr(unsafe.Pointer(inode))) out.Ino = attr.Ino out.EntryValid = 1000 out.AttrValid = 1000 constor.log("%s", id) return fuse.OK }
func (constor *Constor) Lookup(header *fuse.InHeader, name string, out *fuse.EntryOut) fuse.Status { constor.log("%d %s", header.NodeId, name) var stat syscall.Stat_t parent, err := constor.inodemap.findInode(header.NodeId) if err != nil { return fuse.ToStatus(err) } path, err := constor.dentrymap.getPathName(parent.ino, name) if err != nil { return fuse.ToStatus(err) } li := constor.getLayer(path) if li == -1 { return fuse.ENOENT } pathl := Path.Join(constor.layers[li], path) if constor.isdeleted(pathl) { return fuse.ENOENT } err = constor.Lstat(path, &stat) if err != nil { return fuse.ToStatus(err) } constor.log("%s(%d) %d", path, li, stat.Ino) inode, err := constor.inodemap.findInode(stat.Ino) if err != nil { inode = NewInode(constor, stat.Ino) inode.mode = stat.Mode inode.layer = li constor.inodemap.hashInode(inode) } else { inode.layer = li inode.lookup() } if dentry, err := constor.dentrymap.findDentry(parent.ino, inode.ino); err != nil { dentry = new(Dentry) dentry.ino = inode.ino dentry.name = name dentry.parentino = parent.ino constor.dentrymap.hashDentry(dentry) } attr := (*fuse.Attr)(&out.Attr) attr.FromStat(&stat) out.NodeId = attr.Ino out.Ino = attr.Ino constor.log("%d", out.Ino) return fuse.OK }
func (m *fileSystemMount) fillEntry(out *fuse.EntryOut) { splitDuration(m.options.EntryTimeout, &out.EntryValid, &out.EntryValidNsec) splitDuration(m.options.AttrTimeout, &out.AttrValid, &out.AttrValidNsec) m.setOwner(&out.Attr) if out.Mode&fuse.S_IFDIR == 0 && out.Nlink == 0 { out.Nlink = 1 } }
// Creates a return entry for a non-existent path. func (m *fileSystemMount) negativeEntry(out *fuse.EntryOut) bool { if m.options.NegativeTimeout > 0.0 { out.NodeId = 0 splitDuration(m.options.NegativeTimeout, &out.EntryValid, &out.EntryValidNsec) return true } return false }