-
Notifications
You must be signed in to change notification settings - Fork 341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement file locking: getlk/setlk/setlkw/flock #199
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,12 +167,56 @@ func (f *loopbackFile) Fsync(flags int) (code fuse.Status) { | |
return r | ||
} | ||
|
||
func (f *loopbackFile) Flock(flags int) fuse.Status { | ||
f.lock.Lock() | ||
r := fuse.ToStatus(syscall.Flock(int(f.File.Fd()), flags)) | ||
f.lock.Unlock() | ||
const ( | ||
F_OFD_GETLK = 36 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this looks like a syscall interface. Is this the same on OSX ? I would expect this defs to be a linux-specific file (I assume you wrote and tested this under linux.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We tested these constant on OSX and they seem to be working. |
||
F_OFD_SETLK = 37 | ||
F_OFD_SETLKW = 38 | ||
) | ||
|
||
return r | ||
func (f *loopbackFile) GetLk(owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (code fuse.Status) { | ||
flk := syscall.Flock_t{} | ||
lk.ToFlockT(&flk) | ||
code = fuse.ToStatus(syscall.FcntlFlock(f.File.Fd(), F_OFD_GETLK, &flk)) | ||
out.FromFlockT(&flk) | ||
return | ||
} | ||
|
||
func (f *loopbackFile) SetLk(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) { | ||
return f.setLock(owner, lk, flags, false) | ||
} | ||
|
||
func (f *loopbackFile) SetLkw(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) { | ||
return f.setLock(owner, lk, flags, true) | ||
} | ||
|
||
func (f *loopbackFile) setLock(owner uint64, lk *fuse.FileLock, flags uint32, blocking bool) (code fuse.Status) { | ||
if (flags & fuse.FUSE_LK_FLOCK) != 0 { | ||
var op int | ||
switch lk.Typ { | ||
case syscall.F_RDLCK: | ||
op = syscall.LOCK_SH | ||
case syscall.F_WRLCK: | ||
op = syscall.LOCK_EX | ||
case syscall.F_UNLCK: | ||
op = syscall.LOCK_UN | ||
default: | ||
return fuse.EINVAL | ||
} | ||
if !blocking { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if this is controlled from a field in the flags, why have the separate argument 'blocking' ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given this signature:
we understand your comment to mean that So we tested this with the loopback mounter and flock, running:
and
and in fact
In all three cases the It is entirely possible that we have misunderstood. We also haven't tested with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blocking is determined by SetLk vs SetLkw There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it is determined by which one of the methods was called (SetLk or SetLkw) and flags do not indicate whether it is blocking we have to pass a separate argument to |
||
op |= syscall.LOCK_NB | ||
} | ||
return fuse.ToStatus(syscall.Flock(int(f.File.Fd()), op)) | ||
} else { | ||
flk := syscall.Flock_t{} | ||
lk.ToFlockT(&flk) | ||
var op int | ||
if blocking { | ||
op = F_OFD_SETLKW | ||
} else { | ||
op = F_OFD_SETLK | ||
} | ||
return fuse.ToStatus(syscall.FcntlFlock(f.File.Fd(), op, &flk)) | ||
} | ||
} | ||
|
||
func (f *loopbackFile) Truncate(size uint64) fuse.Status { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this wasn't documented well before, but could you add some more wording here? I guess Lkw locks for write and Lk is a concurrent (?) read lock? If you don't want to write docs, add a manpage reference.