diff options
| -rw-r--r-- | internal/fusefrontend/file.go | 2 | ||||
| -rw-r--r-- | internal/fusefrontend/file_allocate_truncate.go | 8 | ||||
| -rw-r--r-- | internal/fusefrontend/file_lock.go | 4 |
3 files changed, 12 insertions, 2 deletions
diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index 813f992..b7ff032 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -258,7 +258,7 @@ func (f *File) Read(ctx context.Context, buf []byte, off int64) (resultData fuse if !(f.rootNode.args.SharedStorage && errno == syscall.EIO) { return nil, errno } - blocks := f.contentEnc.ExplodePlainRange(uint64(off), uint64(len(buf))) + blocks := f.rootNode.contentEnc.ExplodePlainRange(uint64(off), uint64(len(buf))) alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks) if err := f.LockSharedStorage(unix.F_RDLCK, int64(alignedOffset), int64(alignedLength)); err != nil { tlog.Warn.Printf("ino%d: FUSE Read: LockSharedStorage(F_RDLCK, %d, %d) failed: %v", f.qIno.Ino, alignedOffset, alignedLength, err) diff --git a/internal/fusefrontend/file_allocate_truncate.go b/internal/fusefrontend/file_allocate_truncate.go index 3f9cff2..7f1371c 100644 --- a/internal/fusefrontend/file_allocate_truncate.go +++ b/internal/fusefrontend/file_allocate_truncate.go @@ -9,6 +9,8 @@ import ( "sync" "syscall" + "golang.org/x/sys/unix" + "github.com/rfjakob/gocryptfs/v2/internal/contentenc" "github.com/hanwen/go-fuse/v2/fs" @@ -109,6 +111,12 @@ func (f *File) truncate(newSize uint64) (errno syscall.Errno) { f.fileTableEntry.ID = nil return 0 } else { + // Prevent reads and writes concurrent with the truncate operation. It's + // racy on tmpfs and ext4 ( https://lore.kernel.org/all/18e9fa0f-ec31-9107-459c-ae1694503f87@gmail.com/t/ ) + // as evident by TestOpenTruncate test failures. + f.LockSharedStorage(unix.F_WRLCK, 0, 0) + defer f.LockSharedStorage(unix.F_UNLCK, 0, 0) + // With -sharedstorage, we keep the on-disk file header. // Other mounts may have the file ID cached so we cannot mess with it. diff --git a/internal/fusefrontend/file_lock.go b/internal/fusefrontend/file_lock.go index 6f92cfe..bb72c52 100644 --- a/internal/fusefrontend/file_lock.go +++ b/internal/fusefrontend/file_lock.go @@ -6,7 +6,9 @@ import ( "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" ) -// SharedStorageLock conveniently wraps F_OFD_SETLKW +// SharedStorageLock conveniently wraps F_OFD_SETLKW. +// It is a no-op unless args.SharedStorage is set. +// // See https://man7.org/linux/man-pages/man2/fcntl.2.html -> "Open file description locks (non-POSIX)" // // lkType is one of: |
