mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-17 20:10:51 +02:00
With -dlm, GetLk/SetLk/SetLkw and the flush/release cleanup paths go to the inode's owner filer via the PosixLock RPC instead of the local table, so flock/fcntl are honored across mounts. Advisory locking rides the same switch as whole-file write coordination — and is therefore off under writeback cache, which implies single-writer. Keys are the inode identity (HardLinkId else path); SetLkw is client-side polling with the FUSE cancel channel (no server wait queue); a per-mount session id namespaces owners; a local hint avoids a release RPC on every close. Background unlock/release RPCs are bounded so a stuck filer can't hang close().
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
package mount
|
|
|
|
import (
|
|
"syscall"
|
|
|
|
"github.com/seaweedfs/go-fuse/v2/fuse"
|
|
)
|
|
|
|
// GetLk queries for a conflicting lock on the file.
|
|
// If a conflict exists, the conflicting lock is returned in out.
|
|
// If no conflict, out.Lk.Typ is set to F_UNLCK.
|
|
func (wfs *WFS) GetLk(cancel <-chan struct{}, in *fuse.LkIn, out *fuse.LkOut) fuse.Status {
|
|
if wfs.crossMountLocks() {
|
|
return wfs.routedGetLk(cancel, in, out)
|
|
}
|
|
proposed := lockRange{
|
|
Start: in.Lk.Start,
|
|
End: in.Lk.End,
|
|
Typ: in.Lk.Typ,
|
|
Owner: in.Owner,
|
|
Pid: in.Lk.Pid,
|
|
IsFlock: in.LkFlags&fuse.FUSE_LK_FLOCK != 0,
|
|
}
|
|
wfs.posixLocks.GetLk(in.NodeId, proposed, out)
|
|
return fuse.OK
|
|
}
|
|
|
|
// SetLk sets or clears a POSIX lock (non-blocking).
|
|
// Returns EAGAIN if the lock conflicts with an existing lock from another owner.
|
|
func (wfs *WFS) SetLk(cancel <-chan struct{}, in *fuse.LkIn) fuse.Status {
|
|
if wfs.crossMountLocks() {
|
|
return wfs.routedSetLk(cancel, in)
|
|
}
|
|
lk := lockRange{
|
|
Start: in.Lk.Start,
|
|
End: in.Lk.End,
|
|
Typ: in.Lk.Typ,
|
|
Owner: in.Owner,
|
|
Pid: in.Lk.Pid,
|
|
IsFlock: in.LkFlags&fuse.FUSE_LK_FLOCK != 0,
|
|
}
|
|
return wfs.posixLocks.SetLk(in.NodeId, lk)
|
|
}
|
|
|
|
// SetLkw sets a POSIX lock (blocking).
|
|
// Waits until the lock can be acquired or the request is cancelled.
|
|
func (wfs *WFS) SetLkw(cancel <-chan struct{}, in *fuse.LkIn) fuse.Status {
|
|
if wfs.crossMountLocks() {
|
|
return wfs.routedSetLkw(cancel, in)
|
|
}
|
|
lk := lockRange{
|
|
Start: in.Lk.Start,
|
|
End: in.Lk.End,
|
|
Typ: in.Lk.Typ,
|
|
Owner: in.Owner,
|
|
Pid: in.Lk.Pid,
|
|
IsFlock: in.LkFlags&fuse.FUSE_LK_FLOCK != 0,
|
|
}
|
|
if lk.Typ == syscall.F_UNLCK {
|
|
return wfs.posixLocks.SetLk(in.NodeId, lk)
|
|
}
|
|
return wfs.posixLocks.SetLkw(in.NodeId, lk, cancel)
|
|
}
|