diff options
| -rw-r--r-- | internal/fusefrontend/file_lock.go | 19 | ||||
| -rw-r--r-- | internal/syscallcompat/sys_darwin.go | 1 | ||||
| -rw-r--r-- | internal/syscallcompat/sys_linux.go | 1 |
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 |
