aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/fusefrontend/file_lock.go19
-rw-r--r--internal/syscallcompat/sys_darwin.go1
-rw-r--r--internal/syscallcompat/sys_linux.go1
3 files changed, 19 insertions, 2 deletions
diff --git a/internal/fusefrontend/file_lock.go b/internal/fusefrontend/file_lock.go
index f440754..c2965ae 100644
--- a/internal/fusefrontend/file_lock.go
+++ b/internal/fusefrontend/file_lock.go
@@ -4,6 +4,7 @@ import (
"golang.org/x/sys/unix"
"github.com/rfjakob/gocryptfs/v2/internal/syscallcompat"
+ "github.com/rfjakob/gocryptfs/v2/internal/tlog"
)
// SharedStorageLock conveniently wraps F_OFD_SETLKW.
@@ -17,7 +18,7 @@ import (
// * 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 {
+func (f *File) LockSharedStorage(lkType int16, lkStart int64, lkLen int64) (err error) {
if !f.rootNode.args.SharedStorage {
return nil
}
@@ -27,7 +28,21 @@ func (f *File) LockSharedStorage(lkType int16, lkStart int64, lkLen int64) error
Start: lkStart,
Len: lkLen,
}
- return unix.FcntlFlock(uintptr(f.intFd()), syscallcompat.F_OFD_SETLKW, &lk)
+ err = unix.FcntlFlock(uintptr(f.intFd()), syscallcompat.F_OFD_SETLK, &lk)
+ switch err {
+ case unix.EACCES, unix.EAGAIN:
+ tlog.Debug.Printf("LockSharedStorage: waiting for lock")
+ case nil:
+ return
+ }
+ for {
+ err = unix.FcntlFlock(uintptr(f.intFd()), syscallcompat.F_OFD_SETLKW, &lk)
+ if err == unix.EINTR {
+ tlog.Debug.Printf("LockSharedStorage: looping on EINTR")
+ continue
+ }
+ return
+ }
}
// UnlockSharedStorage calls LockSharedStorage with unix.F_UNLCK.
diff --git a/internal/syscallcompat/sys_darwin.go b/internal/syscallcompat/sys_darwin.go
index 17e6a9e..07eb30a 100644
--- a/internal/syscallcompat/sys_darwin.go
+++ b/internal/syscallcompat/sys_darwin.go
@@ -37,6 +37,7 @@ const (
// F_OFD_SETLKW only exists on Linux. On Darwin, fall back to F_SETLKW as a
// flawed replacement.
F_OFD_SETLKW = unix.F_SETLKW
+ F_OFD_SETLK = unix.F_SETLK
)
// Unfortunately fsetattrlist does not have a syscall wrapper yet.
diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go
index 51a2c09..2b8a6f7 100644
--- a/internal/syscallcompat/sys_linux.go
+++ b/internal/syscallcompat/sys_linux.go
@@ -39,6 +39,7 @@ const (
// F_OFD_SETLKW only exists on Linux. On Darwin, fall back to F_SETLKW as a
// flawed replacement.
F_OFD_SETLKW = unix.F_OFD_SETLKW
+ F_OFD_SETLK = unix.F_OFD_SETLK
)
var preallocWarn sync.Once