defer log.Debugln("symlink:", req, l, "err=", err) f := &File{ dir: d, name: req.NewName, link: true, target: req.Target, } err = d.fs.backend.Update(c, func(ctx Context) error { b, err := ctx.Dir(d.path) if err != nil { return err } return b.Put(f.name, f) }) l = f return } var _ = fs.NodeReadlinker(&File{}) func (f *File) Readlink(c context.Context, req *fuse.ReadlinkRequest) (target string, err error) { defer log.Debugln("readlink:", req, target, err) if !f.link { return "", fuse.ENOENT } target = f.target err = nil return }
} attr.Size = uint64(len(file.Contents)) return nil } func (file StupidFile) ReadAll(ctx context.Context) ([]byte, error) { log.Println("File ReadAll") return []byte(file.Contents), nil } // symlinks! type SymlinkFile struct { target string } var _ = fs.Node(&SymlinkFile{}) var _ = fs.NodeReadlinker(&SymlinkFile{}) func (file SymlinkFile) Attr(ctx context.Context, attr *fuse.Attr) error { attr.Mode = os.ModeSymlink attr.Size = uint64(len(file.target)) return nil } func (file SymlinkFile) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) { log.Println("SymlinkFile Readlink to: " + file.target) return file.target, nil }
// +build !openbsd // +build !windows package fuse import ( "bazil.org/fuse" "bazil.org/fuse/fs" "golang.org/x/net/context" "restic" "restic/repository" ) // Statically ensure that *file implements the given interface var _ = fs.NodeReadlinker(&link{}) type link struct { node *restic.Node ownerIsRoot bool } func newLink(repo *repository.Repository, node *restic.Node, ownerIsRoot bool) (*link, error) { return &link{node: node, ownerIsRoot: ownerIsRoot}, nil } func (l *link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) { return l.node.LinkTarget, nil } func (l *link) Attr(ctx context.Context, a *fuse.Attr) error { a.Inode = l.node.Inode