shared storage flag causes getcwd to fail
harporoeder opened this issue · 9 comments
When utilizing the -sharedstorage
flag creating a new shell inside a nested directory causes getcwd
/ pwd
to start failing. This very specifically seems to be a problem with the first level of directories inside a decrypted directory. It does not happen with deeper directories. It does not happen without -sharedstorage
. In my testing I used a totally fresh gocryptfs -init
test bed that was not shared with anything like syncthing. This happens with both bash
and sh
.
Version: gocryptfs v2.0.1; go-fuse [vendored]; 2021-06-07 go1.16.5 linux/amd64
Here is an example:
> cd decrypted
> pwd
/home/user/decrypted
> bash (new shell here)
> pwd
/home/user/decrypted
> exit (exit the shell we just started)
> cd first
> pwd
/home/user/decrypted/first
> bash
> pwd
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
> exit
> pwd
/home/user/decrypted/first
> cd second
> pwd
/home/user/decrypted/first/second
> bash
> pwd
/home/user/decrypted/first/second
> exit
Hi, thanks for the report, could you try latest master? We have better caching now, and as a part of that the directory handling has been refactored.
As for the increasing inode number, this is expected, and prevents hard links from being detected (possibly incorrectly due to concurrent modifications)
Hello @rfjakob
I tested again with master
and have the same result.
> gocryptfs -version
gocryptfs v2.0.1-31-g2a9d70d; go-fuse v2.1.1-0.20210611132105-24a1dfe6b4f8; 2021-07-20 go1.16.5 linux/amd64
Another interesting case with -sharedstorage
enabled:
> cd decrypted/first
> bash
> pwd
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
> cd ..
> pwd
..
> cd first
> pwd
/home/user/decrypted/first
I did a little more digging. I see that stat .
and stat ..
always return the same inode value if you do it a bunch of times however if you stat directory
that counter will update. The shell pwd
built in is doing some caching magic so I tried with /usr/bin/pwd
. Reading the source of /usr/bin/pwd
it does get the inode from stat .
then does a search of ..
for the file that matches that inode. I am able to get this to happen now just using /usr/bin/pwd
and stat
now instead of opening a new shell. I can't fully explain the behavior still.
Perhaps changing stat .
to update the inode in the same way that stat dir
does would fix the issue.
> /usr/bin/pwd
/usr/bin/pwd: couldn't find directory entry in ‘..’ with matching i-node
Thanks for the analysis! Yes that explains it. The unstable inode number breaks the pwd algorithm. Actually, directories cannot have hard links, so I could make those stable.
That the ino of . and .. are stable is strange.
Interstingly, I cannot reproduce this here.
"/tmp/plain" is the mountpoint:
0 jakob@brikett:/tmp/plain$ /usr/bin/pwd
/tmp/plain
0 jakob@brikett:/tmp/plain$ cd subdir/
0 jakob@brikett:/tmp/plain/subdir$ /usr/bin/pwd
/tmp/plain/subdir
"strace /usr/bin/pwd" shows:
getcwd("/tmp/plain/subdir", 4096) = 18
in other words, pwd asked the kernel instead of doing the ino comparison itself. But why doesn't your pwd do that?
I can repro now (don't know why):
1 jakob@brikett:/tmp/plain/subdir$ /usr/bin/pwd
/usr/bin/pwd: couldn't find directory entry in ‘..’ with matching i-node
strace:
getcwd(0x555b239a6500, 4096) = -1 ENOENT (No such file or directory)
I found a much better way to disable hard links, preserving the original inode numbers. This should also fix the getcwd problem.
@rfjakob Thanks for the quick fix! I'll try out master and see how things go. I utilize gocryptfs + syncthing (and have other backups just in case something goes horribly wrong) for lots of my system state, and this should make the experience much better.