Files
seaweedfs/weed/mount/weedfs_file_lock.go
T
Chris Lu 4f692bf9c3 mount: build the package on windows (#10535)
* mount: drop the unused go-fuse fs package dependency

WFS embedded fs.Inode but never used any of its methods, and the only
other reference was RENAME_EXCHANGE, a constant sitting next to three
literals. Removing both drops fs and five internal packages from the
mount build graph.

* mount: build the package on windows

Windows has no fcntl lock types, no O_ACCMODE and no x/sys/unix, so a
handful of constants kept weed/mount pinned to unix even though the code
using them is portable in-memory logic. Route them through per-OS shims
and give setBlksize a windows no-op.

The POSIX lock table now compiles on windows but stays unreachable:
WinFsp resolves byte-range locks in its own kernel driver, so nothing
will feed it there.

go.mod points at a go-fuse branch commit and needs repinning to a release
tag once that lands.

* ci: cross-compile for windows

Nothing caught the unix-only constants creeping into weed/mount until a
release build failed.

* mount: let readdir feed a sink instead of the kernel buffer

doReadDirectory wrote directly into fuse.DirEntryList, which is the
kernel's wire format. A front end that is not the kernel would have to
pack entries only to parse them straight back out.

Route it through DirEntrySink instead. ReadDir and ReadDirPlus pass the
reply buffer, so nothing changes for the FUSE server.

* mount: pin go-fuse v2.9.4 for the windows build
2026-08-03 01:07:49 -07:00

62 lines
1.7 KiB
Go

package mount
import (
"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 == f_UNLCK {
return wfs.posixLocks.SetLk(in.NodeId, lk)
}
return wfs.posixLocks.SetLkw(in.NodeId, lk, cancel)
}