diff options
author | Jakob Unterwurzacher | 2023-06-02 14:24:44 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2023-06-05 14:28:58 +0200 |
commit | 964f0c190932e5dc53b05ec69ccda6e8d33a73b6 (patch) | |
tree | 219f6c02123f0666c795b05e7f1c381690110c4c /internal/fusefrontend/file_lock.go | |
parent | 3058b7978fd8dabd3e8565c9be816b1367bd196a (diff) |
fusefrontend: sharedstorage: use byte-range lock on file header creation
Multiple hosts creating the same file at the same time could
have overwritten each other's file header, leading to data
corruption.
Fix the race by placing a byte-range lock on the file when
creating the file header.
Diffstat (limited to 'internal/fusefrontend/file_lock.go')
-rw-r--r-- | internal/fusefrontend/file_lock.go | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/internal/fusefrontend/file_lock.go b/internal/fusefrontend/file_lock.go new file mode 100644 index 0000000..6f92cfe --- /dev/null +++ b/internal/fusefrontend/file_lock.go @@ -0,0 +1,29 @@ +package fusefrontend + +import ( + "golang.org/x/sys/unix" + + "github.com/rfjakob/gocryptfs/v2/internal/syscallcompat" +) + +// SharedStorageLock conveniently wraps F_OFD_SETLKW +// See https://man7.org/linux/man-pages/man2/fcntl.2.html -> "Open file description locks (non-POSIX)" +// +// lkType is one of: +// * unix.F_RDLCK (shared read lock) +// * unix.F_WRLCK (exclusive write lock) +// * unix.F_UNLCK (unlock) +// +// This function is a no-op if args.SharedStorage == false. +func (f *File) LockSharedStorage(lkType int16, lkStart int64, lkLen int64) error { + if !f.rootNode.args.SharedStorage { + return nil + } + lk := unix.Flock_t{ + Type: lkType, + Whence: unix.SEEK_SET, + Start: lkStart, + Len: lkLen, + } + return unix.FcntlFlock(uintptr(f.intFd()), syscallcompat.F_OFD_SETLKW, &lk) +} |