func (constor *Constor) Open(input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) { pathl, err := constor.getPath(input.NodeId) if err != nil { constor.error("%s", err) return fuse.ToStatus(err) } inode, err := constor.inodemap.findInode(input.NodeId) if err != nil { constor.error("%s", err) return fuse.ToStatus(err) } constor.log("%s %d %d %d", pathl, input.Flags, input.Uid, input.Gid) fd, err := syscall.Open(pathl, int(input.Flags), 0) if err != nil { constor.error("%s", err) return fuse.ToStatus(err) } F := new(FD) F.fd = fd F.flags = int(input.Flags) F.layer = inode.layer constor.putfd(F) out.Fh = uint64(uintptr(unsafe.Pointer(F))) out.OpenFlags = 0 constor.log("%d", out.Fh) return fuse.OK }
func (constor *Constor) Open(input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) { inode := constor.inodemap.findInodePtr(input.NodeId) if inode == nil { return fuse.ENOENT } path := constor.getPath(inode.layer, inode.id) constor.log("%s %d", path, input.Flags) fd, err := syscall.Open(path, int(input.Flags), 0) if err != nil { constor.error("open failed %s : %s", path, err) return fuse.ToStatus(err) } F := new(FD) F.fd = fd F.flags = int(input.Flags) F.layer = inode.layer F.id = inode.id F.pid = input.Pid constor.putfd(F) out.Fh = uint64(uintptr(unsafe.Pointer(F))) if input.Flags&syscall.O_DIRECT != 0 { out.OpenFlags = fuse.FOPEN_DIRECT_IO } else { out.OpenFlags = fuse.FOPEN_KEEP_CACHE } constor.log("%d", out.Fh) return fuse.OK }
func (c *rawBridge) Open(input *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) { node := c.toInode(input.NodeId) f, code := node.fsInode.Open(input.Flags, &input.Context) if !code.Ok() || f == nil { return code } h, opened := node.mount.registerFileHandle(node, nil, f, input.Flags) out.OpenFlags = opened.FuseFlags out.Fh = h return fuse.OK }
func (c *rawBridge) OpenDir(input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) { node := c.toInode(input.NodeId) stream, err := node.fsInode.OpenDir(&input.Context) if err != fuse.OK { return err } stream = append(stream, node.getMountDirEntries()...) de := &connectorDir{ node: node.Node(), stream: append(stream, fuse.DirEntry{Mode: fuse.S_IFDIR, Name: "."}, fuse.DirEntry{Mode: fuse.S_IFDIR, Name: ".."}), rawFS: c, } h, opened := node.mount.registerFileHandle(node, de, nil, input.Flags) out.OpenFlags = opened.FuseFlags out.Fh = h return fuse.OK }
func (constor *Constor) OpenDir(input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) { constor.log("%d", input.NodeId) path, err := constor.dentrymap.getPath(input.NodeId) if err != nil { return fuse.ToStatus(err) } entries := map[string]DirEntry{} for li, layer := range constor.layers { f, err := os.Open(Path.Join(layer, path)) if err != nil { continue } infos, _ := f.Readdir(0) for i := range infos { // workaround forhttps://code.google.com/p/go/issues/detail?id=5960 if infos[i] == nil { continue } name := infos[i].Name() if _, ok := entries[name]; ok { // skip if the file was in upper layer continue } mode := infos[i].Mode() stat := infos[i].Sys().(*syscall.Stat_t) d := DirEntry{ Name: name, Mode: uint32(mode), Ino: stat.Ino, } if li == 0 { err := constor.Lstat(Path.Join(path, name), stat) if err == nil { d.Ino = stat.Ino } } d.Stat = *stat pathl := Path.Join(constor.layers[li], path, name) if constor.isdeleted(pathl) { d.Deleted = true } entries[name] = d } f.Close() } output := make([]DirEntry, 0, 500) for _, d := range entries { if d.Deleted { continue } output = append(output, d) } stat := syscall.Stat_t{} err = constor.Lstat(path, &stat) d := DirEntry{ Name: ".", Mode: stat.Mode, Ino: stat.Ino, } output = append(output, d) err = constor.Lstat(Path.Join(path, ".."), &stat) d = DirEntry{ Name: "..", Mode: stat.Mode, Ino: stat.Ino, } output = append(output, d) for i, _ := range output { output[i].Offset = uint64(i) + 1 } F := new(FD) F.stream = output constor.putfd(F) out.Fh = uint64(uintptr(unsafe.Pointer(F))) out.OpenFlags = 0 return fuse.OK }
func (constor *Constor) OpenDir(input *fuse.OpenIn, out *fuse.OpenOut) (code fuse.Status) { inode := constor.inodemap.findInodePtr(input.NodeId) if inode == nil { constor.log("inode == nil for %d", input.NodeId) return fuse.ENOENT } constor.log("%s", inode.id) entries := map[string]DirEntry{} for li, _ := range constor.layers { path := constor.getPath(li, inode.id) stat := syscall.Stat_t{} err := syscall.Lstat(path, &stat) if err != nil { // continue aggregating upper layers continue } if (stat.Mode & syscall.S_IFMT) != syscall.S_IFDIR { constor.error("Not a dir: %s", path) break } f, err := os.Open(path) if err != nil { constor.error("Open failed on %s", path) break } infos, _ := f.Readdir(0) // reads all entries except "." and ".." for i := range infos { // workaround forhttps://code.google.com/p/go/issues/detail?id=5960 if infos[i] == nil { continue } name := infos[i].Name() if _, ok := entries[name]; ok { // skip if the file was in upper layer continue } d := DirEntry{ Name: name, Mode: uint32(infos[i].Mode()), } if constor.isdeleted(Path.Join(path, name), infos[i].Sys().(*syscall.Stat_t)) { d.Deleted = true } else { id, err := constor.getid(li, inode.id, name) if err != nil { constor.error("getid failed on %d %s %s", li, inode.id, name) continue } d.Ino = idtoino(id) } entries[name] = d } f.Close() } output := make([]DirEntry, 0, 500) for _, d := range entries { if d.Deleted { continue } output = append(output, d) } d := DirEntry{ Name: ".", Mode: syscall.S_IFDIR, Ino: idtoino(inode.id), } output = append(output, d) // FIXME: take care of ".." entry // err = constor.Lstat(Path.Join(path, ".."), &stat) // d = DirEntry{ // Name: "..", // Mode: syscall.S_IFDIR, // } // output = append(output, d) for i, _ := range output { output[i].Offset = uint64(i) + 1 } fmt.Println(output) F := new(FD) if F == nil { return fuse.ToStatus(syscall.ENOMEM) } F.stream = output constor.putfd(F) out.Fh = uint64(uintptr(unsafe.Pointer(F))) out.OpenFlags = 0 return fuse.OK }