Running xfstests generic/075 on tmpfs often triggered a panic
for what seems to be a tmpfs bug.
Quoting from the email to lkml,
http://www.spinics.net/lists/kernel/msg2370127.html :
tmpfs seems to be incorrectly returning 0-bytes when reading from
a file that is concurrently being truncated.
Stat() calls are expensive on NFS as they need a full network
round-trip. We detect when a write immediately follows the
last one and skip the Stat in this case because the write
cannot create a file hole.
On my (slow) NAS, this takes the write speed from 24MB/s to
41MB/s.
Test that we get the right timestamp when extracting a tarball.
Also simplify the workaround in doTestUtimesNano() and fix the
fact that it was running no test at all.
This can happen during normal operation when the directory has
been deleted concurrently. But it can also mean that the
gocryptfs.diriv is missing due to an error, so log the event
at "info" level.
AES-SIV uses 1/2 of the key for authentication, 1/2 for
encryption, so we need a 64-byte key for AES-256. Derive
it from the master key by hashing it with SHA-512.
On a CPU without AES-NI:
$ go test -bench .
Benchmark4kEncStupidGCM-2 50000 24155 ns/op 169.57 MB/s
Benchmark4kEncGoGCM-2 20000 93965 ns/op 43.59 MB/s
Benchmark4kEncGCMSIV-2 500 2576193 ns/op 1.59 MB/s
The last patch added functionality for generating gocryptfs.longname.*
files, this patch adds support for mapping them back to the full
filenames.
Note that resolving a long name needs a full readdir. A cache
will be implemented later on to improve performance.
As ReadDirIV operates on a path anyway, opening the directory
has no clear safety advantage w.r.t. concurrent renames.
If the backing directory is a reverse-mounted gocryptfs filesystem,
each directory open is an OPENDIR, and this causes a full directory
read!
This patch improves the "ls -lR" performance of an
DIR --> gocryptfs-reverse --> gocryptfs
chain by a factor of ~10.
OPENDIR counts for ls -lR:
Before 15570
After 2745
Commit af5441dcd9 has caused a
regression ( https://github.com/rfjakob/gocryptfs/issues/35 )
that is fixed by this commit.
The go-fuse library by now has all the syscall wrappers in
place to correctly handle Utimens, also for symlinks.
Instead of duplicating the effort here just call into go-fuse.
Closes#35
This fixes a build problem on 32-bit hosts:
internal/fusefrontend/file.go:400: cannot use a.Unix() (type int64) as
type int32 in assignment
internal/fusefrontend/file.go:406: cannot use m.Unix() (type int64) as
type int32 in assignment
It also enables full nanosecond timestamps for dates
after 1970.
[...]/stupidgcm/locking.go:16:2:
warning: indirection of non-volatile null pointer will
be deleted, not trap [-Wnull-dereference]
[...]/stupidgcm/locking.go:16:2:
note: consider using __builtin_trap() or qualifying
pointer with 'volatile'
https://github.com/rfjakob/gocryptfs/issues/15
...and convert all calls to syscall.{Fallocate,Openat}
to syscallcompat .
Both syscalls are not available on OSX. We emulate Openat and just
return EOPNOTSUPP for Fallocate.
unPad16 returns detailed errors including the position of the
incorrect bytes. Kill a possible padding oracle by lumping
everything into a generic error.
The detailed error is only logged if debug is active.
We were growing the file block-by-block which was pretty
inefficient. We now coalesce all the grows into a single
Ftruncate. Also simplifies the code!
Simplistic benchmark: Before:
$ time truncate -s 1000M foo
real 0m0.568s
After:
$ time truncate -s 1000M foo
real 0m0.205s
XFS returns a different error code if you try to overwrite
a non-empty directory with a directory:
XFS: mv: cannot move ‘foo’ to ‘bar/foo’: File exists
ext4: mv: cannot move 'foo' to 'bar/foo': Directory not empty
So have EEXIST trigger the Rmdir logic as well.
Fixes issue #20
Link: https://github.com/rfjakob/gocryptfs/issues/20
Drop the date and add the "go-fuse: " prefix so you can see
where the message is coming from.
Before:
Jun 27 09:03:15 brikett gocryptfs[4150]: 2016/06/27 09:03:15 Unimplemented opcode INTERRUPT
After:
Jun 27 09:10:58 brikett gocryptfs[4961]: go-fuse: Unimplemented opcode INTERRUPT
The "!fs.args.DirIV" special case was removed by b17f0465c7
but that, by accident, also removed the handling for
PlaintextNames.
Re-add it as an explicit PlaintextNames special case.
Also adds support for removing directories that miss their
gocryptfs.diriv file for some reason.
...unless "-nosyslog" is passed.
All gocryptfs messages already go to syslog, but the messages
that the go-fuse lib emits were still printed to stdout.
Fixes issue #13 ( https://github.com/rfjakob/gocryptfs/issues/13 )
FUSE filesystems are mounted with "nosuid" by default. If we run as root,
we can use device files by passing the opposite mount option, "suid".
Also we have to use syscall.Chmod instead of os.Chmod because the
portability translation layer "syscallMode" messes up the sgid
and suid bits.
Fixes 70% of the failures in xfstests generic/193. The remaining are
related to truncate, but we err on the safe side:
$ diff -u tests/generic/193.out /home/jakob/src/fuse-xfstests/results//generic/193.out.bad
[...]
check that suid/sgid bits are cleared after successful truncate...
with no exec perm
before: -rwSr-Sr--
-after: -rw-r-Sr--
+after: -rw-r--r--
Support truncate(2) by opening the file and calling ftruncate(2)
While the glibc "truncate" wrapper seems to always use ftruncate, fsstress from
xfstests uses this a lot by calling "truncate64" directly.