aboutsummaryrefslogtreecommitdiff
path: root/internal/fusefrontend
AgeCommit message (Collapse)Author
2024-12-04fusefrontend: sharedstorage: keep file header on truncateJakob Unterwurzacher
With -sharedstorage, we keep the on-disk file header. Other mounts may have the file ID cached so we cannot mess with it. This makes TestOpenTruncate pass.
2024-12-04fusefrontend: sharedstorage: use byte-range lock on file header creationJakob Unterwurzacher
Multiple host writing to the same empty file at the same time could have overwritten each other's newly created file header, leading to data corruption. Fix the race by placing a byte-range lock on the file when creating the file header.
2024-11-11Report inode number for the root nodeJakob Unterwurzacher
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
2024-03-09fusefrontend: fix excessive file fragmentation on BTRFSAlex Shumsky
2023-05-17fusefrontend: implement our own Access()Jakob Unterwurzacher
Not having Access() means go-fuse emulates it by looking at Getattr(). This works fine most of the time, but breaks down on sshfs, where sshfs-benchmark.bash shows this: gocryptfs/tests$ ./sshfs-benchmark.bash nuetzlich.net working directory: /tmp/sshfs-benchmark.bash.JQC sshfs mounted: nuetzlich.net:/tmp -> sshfs.mnt gocryptfs mounted: sshfs.mnt/sshfs-benchmark.bash.Wrz/gocryptfs.crypt -> gocryptfs.mnt sshfs-benchmark.bash: sshfs gocryptfs-on-sshfs git init 3.98 6.80 rsync 7.71 10.84 rm -R 4.30rm: descend into write-protected directory 'gocryptfs.mnt/git1'? The go-fuse emulation gets it wrong here because sshfs reports permissions but does not enforce them. Implement it ourselves properly.
2023-03-29fusefrontent: report correct size on hard link creationJakob Unterwurzacher
And add a test for it. Fixes https://github.com/rfjakob/gocryptfs/issues/724
2023-02-21fusefrontend: unbreak isConsecutiveWrite streaming write optimizationJakob Unterwurzacher
Commit 6196a5b5 got the logic inverted, hence we never set the last position markers. Fixes https://github.com/rfjakob/gocryptfs/issues/712
2023-02-21fusefrontend: doWrite: report readFileID errors as I/O errorJakob Unterwurzacher
It used to be reported as "function not implemented", accompanied with this log output: go-fuse: can't convert error type: ParseHeader: header is all-zero. Header hexdump: 000000000000000000000000000000000000 Now we report EIO and log this: doWrite 1372183: corrupt header: ParseHeader: header is all-zero. Header hexdump: 000000000000000000000000000000000000
2022-12-29make formatJakob Unterwurzacher
Run "make format" using go version go1.19.4 linux/amd64
2022-06-26Fix typosYuta Hayashibe
2022-01-22fusefrontend: support RENAME_WHITEOUT, RENAME_EXCHANGEJakob Unterwurzacher
Both new internal test and xfstests generic/013 are happy. https://github.com/rfjakob/gocryptfs/issues/641
2022-01-10fusefrontend: fix -force_owner not affecting MKNODJakob Unterwurzacher
Fixes https://github.com/rfjakob/gocryptfs/issues/629
2021-12-19fusefrontend: allow slashes in xattr namesJakob Unterwurzacher
xattr names have fewer restrictions than file names, relax the validation. Fixes https://github.com/rfjakob/gocryptfs/issues/627
2021-12-09darwin: use O_NOFOLLOW for xattr opensJakob Unterwurzacher
Running the tests we have lots of these: Openat: O_NOFOLLOW missing: flags = 0x4 -wpanic turns this warning into a panic: Openat: O_NOFOLLOW missing: flags = 0x4 panic: -wpanic turns this warning into a panic: Openat: O_NOFOLLOW missing: flags = 0x4 goroutine 114 [running]: log.(*Logger).Panic(0x14000118280, {0x14000313ca8, 0x1, 0x1}) log/log.go:224 +0x90 github.com/rfjakob/gocryptfs/v2/internal/tlog.(*toggledLogger).Printf(0x14000076780, {0x1009dc2e8, 0x27}, {0x14000313d18, 0x1, 0x1}) github.com/rfjakob/gocryptfs/v2/internal/tlog/log.go:78 +0x168 github.com/rfjakob/gocryptfs/v2/internal/syscallcompat.Openat(0x9, {0x1009d0747, 0x1}, 0x4, 0x0) github.com/rfjakob/gocryptfs/v2/internal/syscallcompat/sys_common.go:59 +0xf0 github.com/rfjakob/gocryptfs/v2/internal/fusefrontend.(*Node).getXAttr(0x14000142000, {0x1400001c140, 0x3a}) github.com/rfjakob/gocryptfs/v2/internal/fusefrontend/node_xattr_darwin.go:30 +0x8c github.com/rfjakob/gocryptfs/v2/internal/fusefrontend.(*Node).Getxattr(0x14000142000, {0x100a7eba0, 0x1400000c2e8}, {0x14000016348, 0x14}, {0x14000326000, 0x20, 0x4000}) github.com/rfjakob/gocryptfs/v2/internal/fusefrontend/node_xattr.go:65 +0x1ac github.com/hanwen/go-fuse/v2/fs.(*rawBridge).GetXAttr(0x1400008e140, 0x140001901e0, 0x140001133c0, {0x14000016348, 0x14}, {0x14000326000, 0x20, 0x4000}) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fs/bridge.go:685 +0x114 github.com/hanwen/go-fuse/v2/fuse.doGetXAttr(0x14000144000, 0x14000113200) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/opcode.go:270 +0x224 github.com/hanwen/go-fuse/v2/fuse.(*Server).handleRequest(0x14000144000, 0x14000113200) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/server.go:499 +0x214 created by github.com/hanwen/go-fuse/v2/fuse.(*Server).loop github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/server.go:470 +0xac https://github.com/rfjakob/gocryptfs/issues/625
2021-10-21nametransform: add longNameMax parameterJakob Unterwurzacher
Determines when to start hashing long names instead of hardcoded 255. Will be used to alleviate "name too long" issues some users see on cloud storage. https://github.com/rfjakob/gocryptfs/issues/499
2021-10-15fusefrontend: honor ForceOwner for LOOKUP and CREATE operationsCharles Duffy
2021-09-10inomap: deterministically set root deviceJakob Unterwurzacher
We used to have "first Translate() wins". This is not deterministic, as the LOOKUP for the root directory does not seem to reach us, so the first user LOOKUP would win, which may be on a mountpoint.
2021-09-10cli: drop -forcedecode flagJakob Unterwurzacher
The rewritten openssl backend does not support this flag anymore, and it was inherently dangerour. Drop it (ignored for compatibility)
2021-08-30fusefrontend: remove leftover PrintfJakob Unterwurzacher
Commit b83ca9c921019fc3b790dabb6198bb77ef2f9a34 inadveredly added a leftover debug Printf. Delete it.
2021-08-30Unbreak hyperlinks broken by go mod v2 conversionJakob Unterwurzacher
Commit 69d88505fd7f4cb0d9e4f1918de296342fe05858 go mod: declare module version v2 translated all instances of "github.com/rfjakob/gocryptfs/" to "github.com/rfjakob/gocryptfs/v2/". Unfortunately, this included hyperlinks. Unbreak the hyperlinks like this: find . -name \*.go | xargs sed -i s%https://github.com/rfjakob/gocryptfs/v2/%https://github.com/rfjakob/gocryptfs/v2/%
2021-08-30Reimplement -serialize_reads flag using new SyncRead mount flagJakob Unterwurzacher
Let the kernel do the work for us. See https://github.com/hanwen/go-fuse/commit/15a8bb029a4e1a51e10043c370970596b1fbb737 for more info.
2021-08-30Remove serialize_reads packageJakob Unterwurzacher
Will be replaced by go-fuse's new SyncRead flag. More info: https://github.com/hanwen/go-fuse/issues/395 SyncRead commit: https://github.com/hanwen/go-fuse/commit/15a8bb029a4e1a51e10043c370970596b1fbb737
2021-08-23go mod: declare module version v2Jakob Unterwurzacher
Our git version is v2+ for some time now, but go.mod still declared v1. Hopefully making both match makes https://pkg.go.dev/github.com/rfjakob/gocryptfs/v2 work. All the import paths have been fixed like this: find . -name \*.go | xargs sed -i s%github.com/rfjakob/gocryptfs/%github.com/rfjakob/gocryptfs/v2/%
2021-08-20Implement -deterministic-names: extended -zerodirivJakob Unterwurzacher
-deterministc-names uses all-zero dirivs but does not write them to disk anymore.
2021-08-19Flag -zerodiriv to create all diriv as all zero byte filesJose M Perez
2021-08-19golangci-lint: fix issues found by gosimpleJakob Unterwurzacher
Everything except the if err2.Err == syscall.EOPNOTSUPP case. Gets too confusing when collapsed into a single line. Issues were: $ golangci-lint run --disable-all --enable gosimple mount.go:473:2: S1008: should use 'return strings.HasPrefix(v, "fusermount version")' instead of 'if strings.HasPrefix(v, "fusermount version") { return true }; return false' (gosimple) if strings.HasPrefix(v, "fusermount version") { ^ cli_args.go:258:5: S1002: should omit comparison to bool constant, can be simplified to `args.forcedecode` (gosimple) if args.forcedecode == true { ^ cli_args.go:263:6: S1002: should omit comparison to bool constant, can be simplified to `args.aessiv` (gosimple) if args.aessiv == true { ^ cli_args.go:267:6: S1002: should omit comparison to bool constant, can be simplified to `args.reverse` (gosimple) if args.reverse == true { ^ internal/stupidgcm/stupidgcm.go:227:6: S1002: should omit comparison to bool constant, can be simplified to `g.forceDecode` (gosimple) if g.forceDecode == true { ^ gocryptfs-xray/xray_tests/xray_test.go:23:5: S1004: should use !bytes.Equal(out, expected) instead (gosimple) if bytes.Compare(out, expected) != 0 { ^ gocryptfs-xray/xray_tests/xray_test.go:40:5: S1004: should use !bytes.Equal(out, expected) instead (gosimple) if bytes.Compare(out, expected) != 0 { ^ gocryptfs-xray/paths_ctlsock.go:34:20: S1002: should omit comparison to bool constant, can be simplified to `!eof` (gosimple) for eof := false; eof == false; line++ { ^ tests/reverse/xattr_test.go:19:2: S1008: should use 'return err2.Err != syscall.EOPNOTSUPP' instead of 'if err2.Err == syscall.EOPNOTSUPP { return false }; return true' (gosimple) if err2.Err == syscall.EOPNOTSUPP { ^ internal/fusefrontend/node.go:459:45: S1002: should omit comparison to bool constant, can be simplified to `!nameFileAlreadyThere` (gosimple) if nametransform.IsLongContent(cName2) && nameFileAlreadyThere == false { ^ tests/xattr/xattr_integration_test.go:221:2: S1008: should use 'return err2.Err != syscall.EOPNOTSUPP' instead of 'if err2.Err == syscall.EOPNOTSUPP { return false }; return true' (gosimple) if err2.Err == syscall.EOPNOTSUPP { ^ tests/test_helpers/helpers.go:338:19: S1002: should omit comparison to bool constant, can be simplified to `open` (gosimple) if err != nil && open == true { ^ tests/matrix/concurrency_test.go:121:7: S1004: should use !bytes.Equal(buf, content) instead (gosimple) if bytes.Compare(buf, content) != 0 { ^
2021-08-18Fix issues found by ineffassignJakob Unterwurzacher
gocryptfs$ ineffassign ./... /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/configfile/config_file.go:243:2: ineffectual assignment to scryptHash /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/configfile/config_file.go:272:2: ineffectual assignment to scryptHash /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/file.go:285:3: ineffectual assignment to fileID /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/node.go:367:3: ineffectual assignment to err /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/node_open_create.go:68:2: ineffectual assignment to fd /home/jakob/go/src/github.com/rfjakob/gocryptfs/mount.go:308:2: ineffectual assignment to masterkey /home/jakob/go/src/github.com/rfjakob/gocryptfs/gocryptfs-xray/xray_main.go:156:13: ineffectual assignment to err /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/fusefrontend/prepare_syscall_test.go:65:16: ineffectual assignment to errno /home/jakob/go/src/github.com/rfjakob/gocryptfs/internal/syscallcompat/open_nofollow_test.go:34:2: ineffectual assignment to fd /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/defaults/acl_test.go:111:6: ineffectual assignment to err /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/defaults/acl_test.go:181:2: ineffectual assignment to sz /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/defaults/acl_test.go:198:2: ineffectual assignment to sz /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/defaults/main_test.go:365:8: ineffectual assignment to err /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/xattr/xattr_fd_test.go:30:6: ineffectual assignment to err /home/jakob/go/src/github.com/rfjakob/gocryptfs/tests/xattr/xattr_fd_test.go:66:6: ineffectual assignment to err
2021-08-16reverse mode: implement -one-file-systemJakob Unterwurzacher
Fixes https://github.com/rfjakob/gocryptfs/issues/475
2021-08-11syscallcompat: move quirks logic here & fix darwinJakob Unterwurzacher
We need to look at f_fstypename acc. to https://stackoverflow.com/a/52299141/1380267 : > As filesystem type numbers are now assigned at runtime in > recent versions of MacOS, you must use f_fstypename to > determine the type. https://github.com/rfjakob/gocryptfs/issues/585
2021-08-02fusefrontend: add quirks for MacOS ExFATJakob Unterwurzacher
This also moves the quirks logic into fusefrontend. Fixes https://github.com/rfjakob/gocryptfs/issues/585
2021-07-31fusefrontend: -sharedstorage: present stable inode numbersJakob Unterwurzacher
Use the Gen field (inode generation) to distinguish hard links while passing the real inode numbers to userspace. Fixes https://github.com/rfjakob/gocryptfs/issues/584
2021-07-31fusefrontend: prepareAtSyscall: handle error when opening ourselvesJakob Unterwurzacher
Error handling was missing here, so we would later get confusing EBADF errors due to dirfd being -1.
2021-07-29fusefrontend: implement fsync on directoriesJakob Unterwurzacher
Fixes https://github.com/rfjakob/gocryptfs/issues/587
2021-06-26fusefrontend: delete openBackingDirJakob Unterwurzacher
2021-06-26fusefrontend: convert last callers from openBackingDir to prepareAtSyscallJakob Unterwurzacher
2021-06-26fusefrontend: ctlsock: get rid of unneccessary wrapper functionJakob Unterwurzacher
2021-06-26fusefrontend: convert ctlsock from openBackingDir to prepareAtSyscallJakob Unterwurzacher
openBackingDir will be removed. Also, remove leftover debug printfs.
2021-06-26fusefrontend: convert openBackingDir tests to prepareAtSyscallJakob Unterwurzacher
openBackingDir will be removed.
2021-06-25fusefrontend: implement recursive diriv cachingJakob Unterwurzacher
The new contrib/maxlen.bash showed that we have exponential runtime with respect to directory depth. The new recursive diriv caching is a lot smarter as it caches intermediate lookups. maxlen.bash now completes in a few seconds. xfstests results same as https://github.com/rfjakob/fuse-xfstests/blob/2d158e4c82be85c15269af77498e353f928f4fab/screenlog.0 : Failures: generic/035 generic/062 generic/080 generic/093 generic/099 generic/215 generic/285 generic/319 generic/426 generic/444 generic/467 generic/477 generic/523 Failed 13 of 580 tests benchmark.bash results are identical: $ ./benchmark.bash Testing gocryptfs at /tmp/benchmark.bash.BdQ: gocryptfs v2.0.1-17-g6b09bc0; go-fuse v2.1.1-0.20210611132105-24a1dfe6b4f8; 2021-06-25 go1.16.5 linux/amd64 /tmp/benchmark.bash.BdQ.mnt is a mountpoint WRITE: 262144000 bytes (262 MB, 250 MiB) copied, 0,4821 s, 544 MB/s READ: 262144000 bytes (262 MB, 250 MiB) copied, 0,266061 s, 985 MB/s UNTAR: 8,280 MD5: 4,564 LS: 1,745 RM: 2,244
2021-06-21nametransform: delete NameTransformer interfaceJakob Unterwurzacher
Useless layer of indirection.
2021-06-20nametransform: pass badname patterns via NewJakob Unterwurzacher
This means we can unexport the field.
2021-06-20Badname file content accessDerDonut
This proposal is the counterpart of the modifications from the `-badname` parameter. It modifies the plain -> cipher mapping for filenames when using `-badname` parameter. The new function `EncryptAndHashBadName` tries to find a cipher filename for the given plain name with the following steps: 1. If `badname` is disabled or direct mapping is successful: Map directly (default and current behaviour) 2. If a file with badname flag has a valid cipher file, this is returned (=File just ends with the badname flag) 3. If a file with a badname flag exists where only the badname flag was added, this is returned (=File cipher name could not be decrypted by function `DecryptName` and just the badname flag was added) 4. Search for all files which cipher file name extists when cropping more and more characters from the end. If only 1 file is found, return this 5. Return an error otherwise This allows file access in the file browsers but most important it allows that you rename files with undecryptable cipher names in the plain directories. Renaming those files will then generate a proper cipher filename One backdraft: When mounting the cipher dir with -badname parameter, you can never create (or rename to) files whose file name ends with the badname file flag (at the moment this is " GOCRYPTFS_BAD_NAME"). This will cause an error. I modified the CLI test function to cover additional test cases. Test [Case 7](https://github.com/DerDonut/gocryptfs/blob/badnamecontent/tests/cli/cli_test.go#L712) cannot be performed since the cli tests are executed in panic mode. The testing is stopped on error. Since the function`DecryptName` produces internal errors when hitting non-decryptable file names, this test was omitted. This implementation is a proposal where I tried to change the minimum amount of existing code. Another possibility would be instead of creating the new function `EncryptAndHashBadName` to modify the signature of the existing function `EncryptAndHashName(name string, iv []byte)` to `EncryptAndHashName(name string, iv []byte, dirfd int)` and integrate the functionality into this function directly. You may allow calling with dirfd=-1 or other invalid values an then performing the current functionality.
2021-06-06fusefronted: report plaintext size on symlink creationJakob Unterwurzacher
gocryptfs 2.0 introduced the regression that the size reported at symlink creation was the ciphertext size, which is wrong. Report the plaintext size. Fixes https://github.com/rfjakob/gocryptfs/issues/574
2021-06-05syscallcompat: drop obsolete wrappersJakob Unterwurzacher
These are now available cross-platform in the unix package.
2021-06-02fusefrontend: run acl Setxattr in user contextJakob Unterwurzacher
The result of setting an acl depends on who runs the operation! Fixes fuse-xfstests generic/375 (see https://github.com/rfjakob/fuse-xfstests/wiki/results_2021-05-19)
2021-06-02fusefrontend: catch ReadAt integer overflowJakob Unterwurzacher
Discovered by xfstests generic/564 . Failure was: generic/564 - output mismatch (see /opt/fuse-xfstests/results//generic/564.out.bad) --- tests/generic/564.out 2021-05-08 21:11:05.307395966 +0200 +++ /opt/fuse-xfstests/results//generic/564.out.bad 2021-05-19 19:01:16.912888879 +0200 @@ -31,7 +31,7 @@ source range beyond 8TiB returns 0 destination range beyond 8TiB returns EFBIG -copy_range: File too large +copy_range: Function not implemented
2021-06-02nametransform: check name validity on encryptionJakob Unterwurzacher
xfstests generic/523 discovered that we allowed to set xattrs with "/" in the name, but did not allow to read them later. With this change we do not allow to set them in the first place.
2021-05-29fusefrontend: list "." and ".." in dir entriesJakob Unterwurzacher
Fixes xfstests generic/401
2021-05-29fusefrontend: rewrite Lseek SEEK_DATA / SEEK_HOLEJakob Unterwurzacher
In response to the discussion of the xfstests mailing list [1], I looked at the Lseek implementation, which was naive and did not handle all cases correctly. The new implementation aligns the returned values to 4096 bytes as most callers expect. A lot of tests are added to verify that we handle all cases correctly now. [1]: https://www.spinics.net/lists/fstests/msg16554.html
2021-05-22syscallcompat: refactor MkdiratUser to take fuse.ContextJakob Unterwurzacher
Let's have MkdiratUser take fuse.Context like everybody else.