Closed JakWai01 closed 2 years ago
[…] was wondering if anybody else can reproduce it.
I just tried reproducing the issue, but for me, the memfs test passes on Fedora 35:
--- PASS: TestMemFS (6.25s)
I wonder what’s different on your system
Thanks for investigating! I also had this issue on Fedora 35 first. I now switched to Ubuntu 21.10 and am still experiencing the same issue. The test actually work for me as well. But as soon as I use it "manually" I can't write files. I created a repository to reproduce this issue by just providing a main.go
and using memfs.go
and inode.go
from the jacobsa/fuse
repository (https://github.com/JakWai01/sile-fystem).
When running said main.go
using go run main.go --mountpoint "test"
, I can't write to files in the "test" directory. Of course, the directory test
needs to be created in the repo first. The directory can be unmounted later by using sudo umount -lf test
.
When using Gedit I get: Unexpected error: Error writing to file: Invalid argument
and when using vim I get: "test" E667: Fsync failed WARNING: Original file may be lost or damaged don't quit the editor until the file is successfully written!
.
As soon as I remove the PID-Check this issue is then resolved for me.
Thanks for the steps to reproduce.
I checked out your https://github.com/JakWai01/sile-fystem repository at git revision 6ea23e4727308ea00e21cbc929ce71be094ca1f2.
I used go run main.go memfs --mp test
to mount the file system.
This is the log output I see when writing a file, where pid is indeed set to 0:
[…]
{"time":1641764410,"level":"DEBUG","event":"FUSE.WriteFile","data":[{"handle":0,"inode":2120192514,"offset":0,"opContext":{"Pid":0}}]}
[…]
Looking at the kernel source code, the uid, gid and pid fields are always sent, except if nocreds
is set. Per https://elixir.bootlin.com/linux/v5.15.13/C/ident/nocreds, nocreds is checked in a few places, but set only for RELEASE, DESTROY and INIT requests, and the only place where it’s set for WRITE requests is https://elixir.bootlin.com/linux/v5.15.13/source/fs/fuse/file.c#L1670
This function is only called from the page cache writeback code path, where the association with an individual pid has been lost.
Indeed, as soon as I add DisableWritebackCaching: true
to the &fuse.MountConfig{}
literal in mount_memfs.go
, I get pids from the Linux kernel with my writes:
[…]
{"time":1641767910,"level":"DEBUG","event":"FUSE.WriteFile","data":[{"handle":0,"inode":2749445729,"offset":0,"opContext":{"Pid":24391}}]}
[…]
Looking back at memfs, I can see the following lines in memfs_test.go, which explains why the memfs test works, but not the memfs sample program itself: https://github.com/jacobsa/fuse/blob/1b9b09fd17a4bbee89a506fdccefbd9d1d414a0c/samples/memfs/memfs_test.go#L100-L101
So, in summary:
Thanks for the detailed explanation. Should I work on moving the writeback caching to memfs?
Yes, if you could send a PR to move the DisableWritebackCaching into memfs itself, that’d be great!
Problem
In my case, the WriteFile function in the memfs example does not work as the PID check triggers and fuse.EINVAL is returned. This is because apparently WriteFile is only invoked by PID 0. If I remove this condition, everything works appropriately. I do not really understand what causes this issue and was wondering if anybody else can reproduce it. If so, i can submit a PR fixing the issue by removing the PID check for this function.
To reproduce this issue, running the memfs example after wrapping the PID check in the WriteFile function with some print statements:
If you can see "Before" but not "After" after writing to a file, this issue affects you as well.
Thanks for your work!
Jakob