diff options
| author | Jakob Unterwurzacher | 2024-11-11 22:27:42 +0100 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2024-11-11 22:33:07 +0100 | 
| commit | 86891054ef2a5d1b0b59c7c140aae284e7c5bd87 (patch) | |
| tree | 7e863db4486656fd18ed5a1144e0669fb085bf58 | |
| parent | 12c0f3a0bdd11444b8bf880af7c63ea7850391f2 (diff) | |
Report inode number for the root node
Now that https://github.com/hanwen/go-fuse/issues/399 has
landed we can report an inode number for the root node.
Fixes https://github.com/rfjakob/gocryptfs/issues/580
| -rw-r--r-- | internal/fusefrontend/root_node.go | 15 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/root_node.go | 15 | ||||
| -rw-r--r-- | mount.go | 7 | ||||
| -rw-r--r-- | tests/matrix/matrix_test.go | 10 | ||||
| -rw-r--r-- | tests/plaintextnames/plaintextnames_test.go | 10 | 
5 files changed, 53 insertions, 4 deletions
| diff --git a/internal/fusefrontend/root_node.go b/internal/fusefrontend/root_node.go index 39cdef7..ac814ad 100644 --- a/internal/fusefrontend/root_node.go +++ b/internal/fusefrontend/root_node.go @@ -59,13 +59,16 @@ type RootNode struct {  	// quirks is a bitmap that enables workaround for quirks in the filesystem  	// backing the cipherdir  	quirks uint64 +	// rootIno is the inode number that we report for the root node on mount +	rootIno uint64  }  func NewRootNode(args Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *RootNode {  	var rootDev uint64  	var st syscall.Stat_t -	if err := syscall.Stat(args.Cipherdir, &st); err != nil { -		tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, err) +	var statErr error +	if statErr = syscall.Stat(args.Cipherdir, &st); statErr != nil { +		tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, statErr)  	} else {  		rootDev = uint64(st.Dev)  	} @@ -87,6 +90,10 @@ func NewRootNode(args Args, c *contentenc.ContentEnc, n *nametransform.NameTrans  		dirCache:      dirCache{ivLen: ivLen},  		quirks:        syscallcompat.DetectQuirks(args.Cipherdir),  	} +	if statErr == nil { +		rn.inoMap.TranslateStat(&st) +		rn.rootIno = st.Ino +	}  	return rn  } @@ -288,3 +295,7 @@ func (rn *RootNode) decryptXattrName(cAttr string) (attr string, err error) {  	}  	return attr, nil  } + +func (rn *RootNode) RootIno() uint64 { +	return rn.rootIno +} diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go index 9de81b5..cb04151 100644 --- a/internal/fusefrontend_reverse/root_node.go +++ b/internal/fusefrontend_reverse/root_node.go @@ -51,6 +51,8 @@ type RootNode struct {  	// bizarre problems when inode numbers are reused behind our back,  	// like this one: https://github.com/rfjakob/gocryptfs/issues/802  	gen uint64 +	// rootIno is the inode number that we report for the root node on mount +	rootIno uint64  }  // NewRootNode returns an encrypted FUSE overlay filesystem. @@ -59,9 +61,10 @@ type RootNode struct {  func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *RootNode {  	var rootDev uint64  	var st syscall.Stat_t +	var statErr error  	var shortNameMax int -	if err := syscall.Stat(args.Cipherdir, &st); err != nil { -		tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, err) +	if statErr = syscall.Stat(args.Cipherdir, &st); statErr != nil { +		tlog.Warn.Printf("Could not stat backing directory %q: %v", args.Cipherdir, statErr)  		if args.OneFileSystem {  			tlog.Fatal.Printf("This is a fatal error in combination with -one-file-system")  			os.Exit(exitcodes.CipherDir) @@ -81,6 +84,10 @@ func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransf  		rootDev:       rootDev,  		shortNameMax:  shortNameMax,  	} +	if statErr == nil { +		rn.inoMap.TranslateStat(&st) +		rn.rootIno = st.Ino +	}  	if len(args.Exclude) > 0 || len(args.ExcludeWildcard) > 0 || len(args.ExcludeFrom) > 0 {  		rn.excluder = prepareExcluder(args)  	} @@ -171,3 +178,7 @@ func (rn *RootNode) uniqueStableAttr(mode uint32, ino uint64) fs.StableAttr {  		Gen: atomic.AddUint64(&rn.gen, 1),  	}  } + +func (rn *RootNode) RootIno() uint64 { +	return rn.rootIno +} @@ -351,6 +351,10 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f  	return rootNode, func() { cCore.Wipe() }  } +type RootInoer interface { +	RootIno() uint64 +} +  // initGoFuse calls into go-fuse to mount `rootNode` on `args.mountpoint`.  // The mountpoint is ready to use when the functions returns.  // On error, it calls os.Exit and does not return. @@ -375,6 +379,9 @@ func initGoFuse(rootNode fs.InodeEmbedder, args *argContainer) *fuse.Server {  		}  	}  	fuseOpts.NullPermissions = true +	// The inode number for the root node must be manually set on mount +	// https://github.com/hanwen/go-fuse/issues/399 +	fuseOpts.RootStableAttr = &fs.StableAttr{Ino: rootNode.(RootInoer).RootIno()}  	// Enable go-fuse warnings  	fuseOpts.Logger = log.New(os.Stderr, "go-fuse: ", log.Lmicroseconds)  	fuseOpts.MountOptions = fuse.MountOptions{ diff --git a/tests/matrix/matrix_test.go b/tests/matrix/matrix_test.go index 0d9c22c..417e126 100644 --- a/tests/matrix/matrix_test.go +++ b/tests/matrix/matrix_test.go @@ -972,3 +972,13 @@ func TestPwd(t *testing.T) {  		os.Mkdir(dir, 0700)  	}  } + +// TestRootIno checks that inode number of the root dir is set +// https://github.com/hanwen/go-fuse/issues/399 +func TestRootIno(t *testing.T) { +	var st syscall.Stat_t +	syscall.Stat(test_helpers.DefaultPlainDir, &st) +	if st.Ino == 0 { +		t.Errorf("inode number of root dir is zero") +	} +} diff --git a/tests/plaintextnames/plaintextnames_test.go b/tests/plaintextnames/plaintextnames_test.go index 8892c39..4de0730 100644 --- a/tests/plaintextnames/plaintextnames_test.go +++ b/tests/plaintextnames/plaintextnames_test.go @@ -125,3 +125,13 @@ func TestInoReuseEvil(t *testing.T) {  		t.Logf("file ino = %d", st.Ino)  	}  } + +// TestRootIno checks that inode number of the root dir is set +// https://github.com/hanwen/go-fuse/issues/399 +func TestRootIno(t *testing.T) { +	var st syscall.Stat_t +	syscall.Stat(cDir, &st) +	if st.Ino == 0 { +		t.Errorf("inode number of root dir is zero") +	} +} | 
