summaryrefslogtreecommitdiff
path: root/internal/fusefrontend_reverse/node.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2020-08-01 21:13:00 +0200
committerJakob Unterwurzacher2020-08-01 21:14:33 +0200
commitf54d21c38427e68b598546c1c870a289cb5e99bb (patch)
treeeeb3a55f70a3cb105a0da8e46ad6423f98da0401 /internal/fusefrontend_reverse/node.go
parent18b3bdb1584fd8e3dde89a95c0dfff910dd95ae1 (diff)
v2api/reverse: implement Lookup & Getattr
Diffstat (limited to 'internal/fusefrontend_reverse/node.go')
-rw-r--r--internal/fusefrontend_reverse/node.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/node.go b/internal/fusefrontend_reverse/node.go
index 6a1294a..a102a66 100644
--- a/internal/fusefrontend_reverse/node.go
+++ b/internal/fusefrontend_reverse/node.go
@@ -1,7 +1,15 @@
package fusefrontend_reverse
import (
+ "context"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+
"github.com/hanwen/go-fuse/v2/fs"
+ "github.com/hanwen/go-fuse/v2/fuse"
+
+ "github.com/rfjakob/gocryptfs/internal/syscallcompat"
)
// Node is a file or directory in the filesystem tree
@@ -9,3 +17,61 @@ import (
type Node struct {
fs.Inode
}
+
+// Lookup - FUSE call for discovering a file.
+// TODO handle virtual files
+func (n *Node) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) {
+ dirfd, cName, errno := n.prepareAtSyscall(name)
+ if errno != 0 {
+ return
+ }
+ defer syscall.Close(dirfd)
+
+ // Get device number and inode number into `st`
+ st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW)
+ if err != nil {
+ return nil, fs.ToErrno(err)
+ }
+
+ // Create new inode and fill `out`
+ ch = n.newChild(ctx, st, out)
+
+ // Translate ciphertext size in `out.Attr.Size` to plaintext size
+ n.translateSize(dirfd, cName, &out.Attr)
+
+ return ch, 0
+}
+
+// GetAttr - FUSE call for stat()ing a file.
+//
+// GetAttr is symlink-safe through use of openBackingDir() and Fstatat().
+func (n *Node) Getattr(ctx context.Context, f fs.FileHandle, out *fuse.AttrOut) (errno syscall.Errno) {
+ // If the kernel gives us a file handle, use it.
+ if f != nil {
+ return f.(fs.FileGetattrer).Getattr(ctx, out)
+ }
+
+ dirfd, cName, errno := n.prepareAtSyscall("")
+ if errno != 0 {
+ return
+ }
+ defer syscall.Close(dirfd)
+
+ st, err := syscallcompat.Fstatat2(dirfd, cName, unix.AT_SYMLINK_NOFOLLOW)
+ if err != nil {
+ return fs.ToErrno(err)
+ }
+
+ // Fix inode number
+ rn := n.rootNode()
+ rn.inoMap.TranslateStat(st)
+ out.Attr.FromStat(st)
+
+ // Translate ciphertext size in `out.Attr.Size` to plaintext size
+ n.translateSize(dirfd, cName, &out.Attr)
+
+ if rn.args.ForceOwner != nil {
+ out.Owner = *rn.args.ForceOwner
+ }
+ return 0
+}