- 25 Aug, 2021 4 commits
-
-
Jakob Unterwurzacher authored
all.bash is broken for some time now (since the move to v2?). Rewrite and simplify it using "./..." syntax. And add the binaries that are generated to gitignore. all.bash will be used in the upcomming patch for Github Actions CI. Change-Id: Ia1b2e6bc60486b419408d4efd50bef4b8dd62bae
-
Jakob Unterwurzacher authored
Unfortunately, I broke darwin with the last commit: + GOOS=darwin + GOARCH=amd64 + go build -tags without_openssl -o /dev/null ../../../../pkg/mod/github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825070001-74a933d6/fuse/server.go:122:5: undefined: parseFuseFd ../../../../pkg/mod/github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825070001-74a933d6/fuse/server.go:887:5: undefined: parseFuseFd Move parseFuseFd() to build on all archs to unbreak the build. Change-Id: Ice173cc70a6a95765b56b444623b68ed92382052
-
Jakob Unterwurzacher authored
libfuse introduced [1] a special `/dev/fd/N` syntax for the mountpoint: It means that a privileged parent process: * Opened /dev/fuse * Called mount() on a real mountpoint directory * Inherited the fd to /dev/fuse to us * Informs us about the fd number via /dev/fd/N This functionality is used to allow FUSE mounts inside containers that have neither root permissions nor suid binaries [2], and for the --drop_privileges flag of mount.fuse3 [4] Tested with singularity and gocryptfs and actually works [3]. v2: Added doccomment for NewServer. v3: Added specific error message on Server.Unmount(). v4: Moved mount details to package comment [1] https://github.com/libfuse/libfuse/commit/64e11073b9347fcf9c6d1eea143763ba9e946f70 [2] https://github.com/rfjakob/gocryptfs/issues/590 [3] $ singularity run --fusemount "host:gocryptfs --extpass echo --extpass test /tmp/a /mnt" docker://ubuntu INFO: Using cached SIF image Reading password from extpass program "echo", arguments: ["test"] Decrypting master key bash: /home/jakob/.cargo/env: No such file or directory bash: /home/jakob/.cargo/env: No such file or directory bash: /home/jakob/.cargo/env: No such file or directory Singularity> Filesystem mounted and ready. [4] man mount.fuse3 Change-Id: Ibcc2464b0ef1e3d236207981b487fd9a7d94c910
-
Jakob Unterwurzacher authored
Update the package comment to refer to the fs package instead of nodefs and pathfs, which are deprecated. Change-Id: I317e53152b63b982298a7de29120191488dcd362
-
- 12 Aug, 2021 1 commit
-
-
Jakob Unterwurzacher authored
This makes the function available to testing, which will be used in the next commit. Change-Id: I2df7aaf50748f209964da6f14764e81237d49027
-
- 02 Aug, 2021 2 commits
-
-
Jakob Unterwurzacher authored
We enable FUSE_CAP_ASYNC_READ per default, which means that the kernel can (and does) submit multiple concurrent out-of-order read requests to service userspace reads and kernel readahead. For some backing storages, like Amazon Cloud Drive, out-of-order reads are expensive. gocryptfs has implemented a delay-based workaround with its `-serialize_reads` flag for this case (see https://github.com/rfjakob/gocryptfs/issues/92 for details). Not enabling FUSE_CAP_ASYNC_READ makes the kernel do this for us, as verified by adding debug output to gocryptfs, so expose it as a mount flag in MountOptions. Fixes: https://github.com/hanwen/go-fuse/issues/140 Graphs-at: https://github.com/hanwen/go-fuse/issues/395 Related: https://github.com/rfjakob/gocryptfs/issues/92 Change-Id: I10f947d71e1453989c4a9b66fbb0407f7163994f
-
Jakob Unterwurzacher authored
The root directory always get nodeid 1, and the v2 api originally had "nodeid == inode number". But since 1d0096e5, inode number and node id are independent, and we can allow inode number 1. Why does this matter? MacOS actually uses inode number 1 on ExFAT mounts, triggering a panic on overlay filesystems like gocryptfs: panic: using reserved ID 1 for inode number Fixes: https://github.com/rfjakob/gocryptfs/issues/585 Change-Id: I5e3476da65400d32efdb3dac1fe4901c64c00a89
-
- 01 Aug, 2021 1 commit
-
-
Jakob Unterwurzacher authored
Drops an obsolete entry pointing to go-fuse v1.0.0. Change-Id: Iaf8e880d6f39e63b593a7929b8b4ff649c1d7807
-
- 30 Jul, 2021 2 commits
-
-
Jakob Unterwurzacher authored
The file type is not a bitmap, and looking at S_IFBLK = 0x6000 S_IFCHR = 0x2000 S_IFDIR = 0x4000 S_IFIFO = 0x1000 S_IFLNK = 0xa000 S_IFREG = 0x8000 S_IFSOCK = 0xc000 and confirmed by the added test, we used to classify block devices and sockets as directories: --- FAIL: TestInodeIsDir (0.00s) inode_test.go:25: wrong result for case struct { mode uint32; dir bool }{mode:0x6000, dir:false} inode_test.go:25: wrong result for case struct { mode uint32; dir bool }{mode:0xc000, dir:false} The check is fixed now and the test passes. Change-Id: I6490992d1fecc8a6bea7c2c4b2f1bca765d03d4c
-
Jakob Unterwurzacher authored
This GOMAXPROCS=1 go test -v -count=1 -run TestDeleteNotify ./fuse/test deadlocked reliably, apparently in the chdir() from cmd.Start(). We can do without the chdir() by using an absolte path. This avoids the issue. Fixes https://github.com/hanwen/go-fuse/issues/261 Change-Id: Ia9c8f15819c125c5bf94b085fa4c5f2977a6789a
-
- 11 Jun, 2021 2 commits
-
-
Jakob Unterwurzacher authored
Maps do not free all memory when elements get deleted ( https://github.com/golang/go/issues/20135 ). As a workaround, we recreate our two big maps (kernelNodeIds & stableAttrs) when they have shrunk dramatically (100 x smaller). Benchmarkung with loopback (go version go1.16.2 linux/amd64) shows: Before this change: Step VmRSS (kiB) ----- ----------- Fresh mount 4000 ls -R 500k files 271100 after drop_cache 336448 wait ~ 3 minutes 101588 After: Step VmRSS (kiB) ----- ----------- Fresh mount 4012 ls -R 500k files 271100 after drop_cache 31528 Results for gocryptfs are similar. Has survived xfstests via gocryptfs. Fixes: https://github.com/rfjakob/gocryptfs/issues/569 Change-Id: Idcae1ab953270516735839a034d586717647b8db
-
Jakob Unterwurzacher authored
inoMap & nodeidMap have been renamed a long time ago, but this comment has been missed. Update it for the new names. Change-Id: I5e1d86f5e8ac3b3219b324da09d3f628b3f0fb80
-
- 08 Jun, 2021 1 commit
-
-
Tommy Lindgren authored
If writing the INTERRUPT response returns ENOENT it means that the referred request is no longer known by the kernel. This is a normal if the referred request already has completed. We thus suppress the scary warning unless debugging is enabled. Fixes #375. Change-Id: I3266dbd8ad53a42db9e0e746e4734f284746b76c
-
- 03 Jun, 2021 1 commit
-
-
Jakob Unterwurzacher authored
Enabling the logger shows this helpful warning warning: Inode.Path: n3 is orphaned, replacing segment with ".go-fuse.5577006791947779410/deleted" for the problem reported at https://github.com/hanwen/go-fuse/issues/398 , and it generally makes sense to have complete logs for tests. Enable the logger. Change-Id: I4602f100a31c6e50bc48251a877b97ce3013ff24
-
- 08 May, 2021 2 commits
-
-
Jakob Unterwurzacher authored
Enables kernel ACL enforcement. Change-Id: I7fb5f6f8b350ad430da18e0173df942b98da7c02
-
Jakob Unterwurzacher authored
With CAP_POSIX_ACL = (1 << 20) the ACLs actually work. Change-Id: Ic91e9f8d4196c811d4c566455b0e8c4a7871b105
-
- 23 Apr, 2021 2 commits
-
-
Jakob Unterwurzacher authored
Introduce the new struct inodeParents that wraps a map and one special slot for the most recent parent. Unit tests included. Because the map is lazily initialized, we should save some memory on the common single-parent case (= file with no hard links) compared to before. Benchmarking with gocryptfs shows no discernible change in performance. fsstress testing with gocryptfs shows no issues. TestStaleHardlinks the previous commit passes now. Change-Id: I8d69093abc906addde751a9e70dbd78a3a61371a
-
Jakob Unterwurzacher authored
This test shows a problem in selecting a random path for a node when there is more than one. The failure looks like this: 18:41:50.796468 rx 136: LOOKUP n1 ["link0"] 6b 18:41:50.796489 tx 136: OK, {n2 g1 tE=0s tA=0s {M0100600 SZ=0 L=1 1026:1026 B0*4096 i0:269663 A 1616348510.793212 M 1616348510.793212 C 1616348510.795212}} 18:41:50.796535 rx 138: OPEN n2 {O_RDONLY,0x8000} 18:41:50.796557 tx 138: 2=no such file or directory, {Fh 0 } The LOOKUP succeeds (because the file "link0" is there). But the OPEN fails because go-fuse chooses another (stale) path. I will try to make the behavoir more robust against changes behind our back, but this patch only adds a test to show the problem. Change-Id: I39b31ba717ddaaad7dda6ecd86707c75cd25102e
-
- 12 Apr, 2021 1 commit
-
-
Han-Wen Nienhuys authored
Change-Id: Ide563371
-
- 10 Apr, 2021 2 commits
-
-
Han-Wen Nienhuys authored
Release isn't synchronized, so a quick [close,unlink] sequence may still fail without this delay. Change-Id: I64170fca
-
Han-Wen Nienhuys authored
This is a more complete emulation of Windows FS semantics. Change-Id: If9dec3ebeac808e1cc4f6d234290867c50e87a30
-
- 22 Mar, 2021 1 commit
-
-
Tommy Lindgren authored
This avoids a panic. Change-Id: I5c4cc0d875ecdbc3b07c2322b5a5a5e6fa493709
-
- 01 Feb, 2021 1 commit
-
-
Tommy Lindgren authored
Previously maximum number of requests readers was hard-coded to 2. Setting it to max(2, min(16, GOMAXPROCS)) improves the throughput on systems with more cores available. Going beyond 16 readers seems to hurt performance even if there are more cores available. Benchmark GoFuseRead can be used for demonstrating the effects of this variable. The benchmark reads 32 streams in parallel from a dummy filesystem (read operations immediately return zeros). Example results from an i7-8550U (8 cores): | Max readers | Total throughput | | ----------: | ---------------: | | 2 | 13217 MB/s | | 4 | 19202 MB/s | | 8 | 19973 MB/s | | 16 | 18994 MB/s | On a 96 core system: | Max readers | Total throughput | | ----------: | ---------------: | | 2 | 11490 MB/s | | 4 | 16129 MB/s | | 8 | 24263 MB/s | | 16 | 29568 MB/s | | 32 | 28262 MB/s | Note that improvements won't be as dramatic for real filesytem implementations. In benchmarks for a filesystem doing real work I see a 30-40% improvement (8.3 -> 11.4 GB/s) on the 96 core system. Also tweaked some of the other benchmarks so they don't leave behind mountpoints. Fixes #388. Change-Id: Ibff17d7fc92195f078a9ccff818a31f3a58873f2
-
- 25 Jan, 2021 1 commit
-
-
Jakob Unterwurzacher authored
This test mmap()s a file, which means reading the memory can block, triggering file I/O and FUSE requests. With GOMAXPROCS=1, we don't have a free thread to handle those requests, deadlocking the test: GOMAXPROCS=1 go test -v -count=1 -run TestCacheControl ./fuse/test Use mlock() to fix that, also add a warning to the "fuse" package docs. Fixes https://github.com/hanwen/go-fuse/issues/261 Change-Id: Ia32fb1826c2be602cf4f0f6cf73956af797c940c
-
- 21 Jan, 2021 1 commit
-
-
Han-Wen Nienhuys authored
Make LoopbackNode and LoopbackRoot public, and add an example of how to extend them. Fixes #364. Change-Id: Idcce1bf3765e93ece3bcf9d14de8a957b8c6b63a
-
- 04 Jan, 2021 1 commit
-
-
midchildan authored
Closes #379. Change-Id: Ieb821fe7e68a3b7822306ad620dcdf834b5dfc12
-
- 31 Dec, 2020 1 commit
-
-
Han-Wen Nienhuys authored
Document LoopbackNode, LoopbackRoot. Use loopbackRoot.newNode() for creating new nodes Change-Id: I625c7706
-
- 27 Dec, 2020 4 commits
-
-
Han-Wen Nienhuys authored
Change-Id: I19d52f14f63f1481b2b1aa9dcd46c91fe4e1ad99
-
Han-Wen Nienhuys authored
This leaves only one type to implement for the loopback file system, which will simplify extending the loopback functionality. Change-Id: I8906755f3bdf2ea63557d5bb25f50651521364c7
-
Han-Wen Nienhuys authored
This provides a test for GitHub PR #378, ie. the previous commit Change-Id: I9473722e
-
abitduck authored
Change-Id: I8845cac5c18d2640b46971564f94f7ff1741a0ee
-
- 09 Dec, 2020 1 commit
-
-
Han-Wen Nienhuys authored
On OSX, syscall.O_TRUNC on the Create call apparently triggers a SETATTR call with size 0, which must be responded to correctly. Change-Id: Icb99891eae99ced6ffbd5fb1dadf42ffad687534
-
- 08 Dec, 2020 1 commit
-
-
Han-Wen Nienhuys authored
Some of the error codes due to the poll hack get returned back to the OSX mount process, which leads to failing mounts. Change-Id: I5b10509c3b8173343caf3f67c0e12a25ddfae32b
-
- 01 Dec, 2020 1 commit
-
-
Han-Wen Nienhuys authored
syscall.Dirent declares a 256-byte "name" field. In reality, this field is only as long as necessary to transmit the name, so more entries can be packed in a page. When casting the result to syscall.Dirent, the result might run over the end of the byte buffer, which the race detector doesn't like. Address this by using our own flavor of syscall.Dirent. All linux flavors use the same structure layout, except for the amount of padding at the end. Change-Id: I618f7ef9e167894e1ab25b2113dcd20d7b76ceb4
-
- 04 Nov, 2020 5 commits
-
-
Jakob Unterwurzacher authored
nodeid and inode number used to be identical, which is why both could be marked as "iXXX". This is no longer the case, so make nodeids distinguishable. Example: 23:47:17.637736 rx 9156: MKDIR n28 {0777 (00)} ["d90X"] 5b 23:47:17.637801 tx 9156: OK, {n112 g1 tE=1s tA=1s {M040755 SZ=4096 L=2 1026:1026 B8*4096 i0:2769795 A 1601761637.637385 M 1601761637.637385 C 1601761637.637385}} v4: also update orphaned inode warning Change-Id: Ib29dabfd4cf6692cf4118191f8dc73529562426f
-
Jakob Unterwurzacher authored
Using the inode numbers as the nodeid causes problems when the fs reuses inode numbers. This is the case with any overlay filesystem that is backed by ext4 like the loopback example or gocryptfs. We already had the expSleep() and re-add hack, 7090b027 fs: wait out apparent inode type change 68f70527 fs: addNewChild(): handle concurrent FORGETs to mitigate some of the problems (at the risk of deadlocking forever), but I could not find a way to work around the following case uncovered by fsstress: The kernel expects a fresh nodeid from MKDIR (see #372 for a debug log). This is now guaranteed by passing the O_EXCL to addNewChild(). However, this also means that the hard link detection must happen in addNewChild() as opposed to newInodeUnlocked() before. The expSleep and re-add hacks are no longer needed and have been dropped. This survived 24 hours (42587 iterations) of fsstress testing. Tested was the loopback example running on top of ext4 on Linux 5.8.10. Fixes https://github.com/hanwen/go-fuse/issues/372 . v2: Rename inoMap -> stableAttrs, nodeidMap -> kernelNodeIds acc. to feedback from Han-Wen. v3: initialize Inode.nodeId early v4: drop leftover file stash.txt Change-Id: Ibb36a886f15d48727daa10b9717ea88e45a6b8af
-
Jakob Unterwurzacher authored
With rename and link, it hangs within 20ms, so we can reduce the runtime. Also add deadlock detection & statistics printout. A good run looks like this: $ TMPDIR=/var/tmp go test -run TestFsstress -v === RUN TestFsstress simple_test.go:601: Operation statistics: simple_test.go:604: creat: 33 ok, 132978 fail, 0 hung simple_test.go:604: link: 85 ok, 37196 fail, 0 hung simple_test.go:604: mkdir: 60 ok, 155273 fail, 0 hung simple_test.go:604: mkfifo: 45 ok, 161937 fail, 0 hung simple_test.go:604: mknod_fifo: 55 ok, 154459 fail, 0 hung simple_test.go:604: mknod_reg: 77 ok, 180614 fail, 0 hung simple_test.go:604: mknod_sock: 83 ok, 139479 fail, 0 hung simple_test.go:604: readdir: 13 ok, 0 fail, 0 hung simple_test.go:604: remove: 180 ok, 40 fail, 0 hung simple_test.go:604: rename: 646 ok, 137 fail, 0 hung simple_test.go:604: rmdir: 48 ok, 48342 fail, 0 hung simple_test.go:604: symlink: 30 ok, 119954 fail, 0 hung simple_test.go:604: unlink: 150 ok, 6121 fail, 0 hung --- PASS: TestFsstress (1.02s) PASS ok github.com/hanwen/go-fuse/v2/fs 1.022s A bad run like this: go-fuse/fs$ TMPDIR=/var/tmp go test -run TestFsstress -v === RUN TestFsstress simple_test.go:592: timeout waiting for goroutines to exit (deadlocked?) simple_test.go:601: Operation statistics: simple_test.go:604: creat: 0 ok, 44 fail, 10 hung simple_test.go:604: link: 0 ok, 6 fail, 10 hung simple_test.go:604: mkdir: 1 ok, 283 fail, 10 hung simple_test.go:604: mkfifo: 1 ok, 140 fail, 10 hung simple_test.go:604: mknod_fifo: 1 ok, 1246 fail, 10 hung simple_test.go:604: mknod_reg: 0 ok, 19 fail, 10 hung simple_test.go:604: mknod_sock: 0 ok, 110 fail, 10 hung simple_test.go:604: readdir: 1 ok, 0 fail, 1 hung simple_test.go:604: remove: 1 ok, 0 fail, 10 hung simple_test.go:604: rename: 0 ok, 12 fail, 10 hung simple_test.go:604: rmdir: 1 ok, 346 fail, 10 hung simple_test.go:604: symlink: 1 ok, 1456 fail, 10 hung simple_test.go:604: unlink: 2 ok, 15 fail, 10 hung simple_test.go:51: /usr/bin/fusermount: failed to unmount /var/tmp/TestFsstress302646914/mnt: Device or resource busy (code exit status 1) --- FAIL: TestFsstress (2.30s) FAIL [hangs] Change-Id: I9eb0ce02eb1df766be257d6a87de53c6ffa6d21e
-
Jakob Unterwurzacher authored
TestFsstress is loosely modeled after xfstest's fsstress. It performs rapid parallel removes / creates / readdirs. Coupled with inode reuse, this test used to deadlock go-fuse quite quickly. Change-Id: Ia3af099e08c74d3c160062c1ed414430b6c1e7c9
-
Jakob Unterwurzacher authored
If this happens, it means our node accounting is messed up. Abort the process by panicing instead of wrapping around to UINT_MAX. Change-Id: Id662ab03877d44a16785bfd164a96173a3b7519f
-
- 07 Oct, 2020 1 commit
-
-
Kirill Smelkov authored
If kernel internally serializes lookup requests for a directory, the test will deadlock, becaue it tries to issue two such request and pause lookup handlers, untill both requests come in. For example here is how this test hangs on Ubuntu Xenial 16.04: kirr@kubu:~/t/go-fuse$ go test -count=1 -v -run TestNodeParallelLookup ./fuse/test/ === RUN TestNodeParallelLookup 18:24:38.494651 rx 1: INIT i0 {7.23 Ra 0x20000 POSIX_LOCKS,ATOMIC_O_TRUNC,EXPORT_SUPPORT,DONT_MASK,FLOCK_LOCKS,READDIRPLUS_AUTO,ASYNC_DIO,WRITEBACK_CACHE,SPLICE_WRITE,SPLICE_READ,IOCTL_DIR,AUTO_INVAL_DATA,READDIRPLUS,NO_OPEN_SUPPORT,ASYNC_READ,BIG_WRITES,SPLICE_MOVE} 18:24:38.494713 tx 1: OK, {7.23 Ra 0x20000 ASYNC_READ,BIG_WRITES,AUTO_INVAL_DATA,READDIRPLUS,NO_OPEN_SUPPORT 0/0 Wr 0x10000 Tg 0x0} 18:24:38.495351 rx 2: LOOKUP i1 [".go-fuse-epoll-hack"] 20b 18:24:38.495467 tx 2: OK, {i18446744073709551615 g0 tE=0s tA=0s {M0100644 SZ=0 L=1 0:0 B0*0 i0:18446744073709551615 A 0.000000 M 0.000000 C 0.000000}} 18:24:38.495530 rx 3: OPEN i18446744073709551615 {O_RDONLY,0x8000} 18:24:38.495575 tx 3: OK, {Fh 18446744073709551615 } 18:24:38.495624 rx 4: POLL i18446744073709551615 18:24:38.495659 tx 4: 38=function not implemented 18:24:38.495706 rx 5: FLUSH i18446744073709551615 {Fh 18446744073709551615} 18:24:38.495741 tx 5: 34=numerical result out of range 18:24:38.495812 rx 6: RELEASE i18446744073709551615 {Fh 18446744073709551615 0x8000 L0} 18:24:38.495849 tx 6: 34=numerical result out of range 18:24:38.495904 rx 7: LOOKUP i1 ["world"] 6b 18:24:38.495957 I: <- lookup "world" < hang > Amends: 17c0c400 (nodefs: Allow for several Lookup requests to be served simultaneously) Updates: https://github.com/hanwen/go-fuse/issues/261 Change-Id: I5d0a76d1190af805351326c378f69cf8ff781a37
-