From bb6155a51ff7a521d948ec58723d211bfaf8a731 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 16 Nov 2019 21:36:27 +0100 Subject: [PATCH] fusefrontend: use inummap translate inode numbers on different devices to fix collisions. Fixes https://github.com/rfjakob/gocryptfs/issues/435 --- internal/fusefrontend/file.go | 1 + internal/fusefrontend/fs.go | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index 74a56c3..83e39be 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -462,6 +462,7 @@ func (f *File) GetAttr(a *fuse.Attr) fuse.Status { if err != nil { return fuse.ToStatus(err) } + f.fs.inumMap.TranslateStat(&st) a.FromStat(&st) a.Size = f.contentEnc.CipherSizeToPlainSize(a.Size) if f.fs.args.ForceOwner != nil { diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index fe37d10..b922805 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -19,6 +19,7 @@ import ( "github.com/rfjakob/gocryptfs/internal/configfile" "github.com/rfjakob/gocryptfs/internal/contentenc" "github.com/rfjakob/gocryptfs/internal/nametransform" + "github.com/rfjakob/gocryptfs/internal/openfiletable" "github.com/rfjakob/gocryptfs/internal/serialize_reads" "github.com/rfjakob/gocryptfs/internal/syscallcompat" "github.com/rfjakob/gocryptfs/internal/tlog" @@ -56,8 +57,11 @@ type FS struct { // When -idle was used when mounting, idleMonitor() sets it to 1 // periodically. IsIdle uint32 - + // dirCache caches directory fds dirCache dirCacheStruct + // inumMap translates inode numbers from different devices to unique inode + // numbers. + inumMap *openfiletable.InumMap } //var _ pathfs.FileSystem = &FS{} // Verify that interface is implemented. @@ -70,11 +74,18 @@ func NewFS(args Args, c *contentenc.ContentEnc, n nametransform.NameTransformer) if len(args.Exclude) > 0 { tlog.Warn.Printf("Forward mode does not support -exclude") } + var st syscall.Stat_t + err := syscall.Stat(args.Cipherdir, &st) + if err != nil { + tlog.Warn.Printf("NewFS: could not stat cipherdir: %v", err) + st.Dev = 0 + } return &FS{ FileSystem: pathfs.NewDefaultFileSystem(), args: args, nameTransform: n, contentEnc: c, + inumMap: openfiletable.NewInumMap(st.Dev), } } @@ -98,6 +109,7 @@ func (fs *FS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr, fuse.S } a := &fuse.Attr{} st2 := syscallcompat.Unix2syscall(st) + fs.inumMap.TranslateStat(&st2) a.FromStat(&st2) if a.IsRegular() { a.Size = fs.contentEnc.CipherSizeToPlainSize(a.Size)