Commit e65a2a77 authored by Lucas Manning's avatar Lucas Manning

Fix loopback file locking methods to correctly use the file handle.

Change-Id: I3a67066a6660481bdab81278a91027755973b496
parent 615a0a7e
......@@ -793,7 +793,7 @@ func (b *rawBridge) SetLk(cancel <-chan struct{}, input *fuse.LkIn) fuse.Status
if lops, ok := n.ops.(NodeSetlker); ok {
return errnoToStatus(lops.Setlk(&fuse.Context{Caller: input.Caller, Cancel: cancel}, f.file, input.Owner, &input.Lk, input.LkFlags))
}
if sl, ok := n.ops.(FileSetlker); ok {
if sl, ok := f.file.(FileSetlker); ok {
return errnoToStatus(sl.Setlk(&fuse.Context{Caller: input.Caller, Cancel: cancel}, input.Owner, &input.Lk, input.LkFlags))
}
return fuse.ENOTSUP
......@@ -803,7 +803,7 @@ func (b *rawBridge) SetLkw(cancel <-chan struct{}, input *fuse.LkIn) fuse.Status
if lops, ok := n.ops.(NodeSetlkwer); ok {
return errnoToStatus(lops.Setlkw(&fuse.Context{Caller: input.Caller, Cancel: cancel}, f.file, input.Owner, &input.Lk, input.LkFlags))
}
if sl, ok := n.ops.(FileSetlkwer); ok {
if sl, ok := f.file.(FileSetlkwer); ok {
return errnoToStatus(sl.Setlkw(&fuse.Context{Caller: input.Caller, Cancel: cancel}, input.Owner, &input.Lk, input.LkFlags))
}
return fuse.ENOTSUP
......
......@@ -57,6 +57,7 @@ func (tc *testCase) Clean() {
type testOptions struct {
entryCache bool
enableLocks bool
attrCache bool
suppressDebug bool
testDir string
......@@ -112,6 +113,7 @@ func newTestCase(t *testing.T, opts *testOptions) *testCase {
mOpts := &fuse.MountOptions{
DirectMount: opts.directMount,
DirectMountStrict: opts.directMountStrict,
EnableLocks: opts.enableLocks,
}
if !opts.suppressDebug {
mOpts.Debug = testutil.VerboseTest()
......@@ -390,7 +392,10 @@ func TestPosix(t *testing.T) {
t.Run(nm, func(t *testing.T) {
tc := newTestCase(t, &testOptions{
suppressDebug: noisy[nm],
attrCache: true, entryCache: true})
attrCache: true,
entryCache: true,
enableLocks: true,
})
defer tc.Clean()
fn(t, tc.mntDir)
......@@ -429,7 +434,7 @@ func TestOpenDirectIO(t *testing.T) {
//
// Note: Run as
//
// TMPDIR=/var/tmp go test -run TestFsstress
// TMPDIR=/var/tmp go test -run TestFsstress
//
// to make sure the backing filesystem is ext4. /tmp is tmpfs on modern Linux
// distributions, and tmpfs does not reuse inode numbers, hiding the problem.
......
......@@ -16,6 +16,7 @@ import (
"testing"
"github.com/hanwen/go-fuse/v2/fuse"
"golang.org/x/sys/unix"
)
// All holds a map of all test functions
......@@ -41,6 +42,8 @@ var All = map[string]func(*testing.T, string){
"OpenAt": OpenAt,
"Fallocate": Fallocate,
"DirSeek": DirSeek,
"FcntlFlockSetLk": FcntlFlockSetLk,
"FcntlFlockLocksFile": FcntlFlockLocksFile,
}
func DirectIO(t *testing.T, mnt string) {
......@@ -631,3 +634,67 @@ func Fallocate(t *testing.T, mnt string) {
fi.Size())
}
}
func FcntlFlockSetLk(t *testing.T, mnt string) {
for i, cmd := range []int{syscall.F_SETLK, syscall.F_SETLKW} {
filename := mnt + fmt.Sprintf("/file%d", i)
f1, err := os.Create(filename)
if err != nil {
t.Fatalf("Open failed: %v", err)
}
defer f1.Close()
wlk := syscall.Flock_t{
Type: syscall.F_WRLCK,
Start: 0,
Len: 0,
}
if err := syscall.FcntlFlock(f1.Fd(), cmd, &wlk); err != nil {
t.Fatalf("FcntlFlock failed: %v", err)
}
f2, err := os.OpenFile(filename, os.O_RDWR, 0766)
if err != nil {
t.Fatalf("Open failed: %v", err)
}
defer f2.Close()
lk := syscall.Flock_t{}
if err := syscall.FcntlFlock(f2.Fd(), unix.F_OFD_GETLK, &lk); err != nil {
t.Errorf("FcntlFlock failed: %v", err)
}
if lk.Type != syscall.F_WRLCK {
t.Errorf("got lk.Type=%v, want %v", lk.Type, syscall.F_WRLCK)
}
}
}
func FcntlFlockLocksFile(t *testing.T, mnt string) {
filename := mnt + "/test"
f1, err := os.Create(filename)
if err != nil {
t.Fatalf("Open failed: %v", err)
}
defer f1.Close()
wlk := syscall.Flock_t{
Type: syscall.F_WRLCK,
Start: 0,
Len: 0,
}
if err := syscall.FcntlFlock(f1.Fd(), syscall.F_SETLK, &wlk); err != nil {
t.Fatalf("FcntlFlock failed: %v", err)
}
f2, err := os.OpenFile(filename, os.O_RDWR, 0766)
if err != nil {
t.Fatalf("Open failed: %v", err)
}
defer f2.Close()
rlk := syscall.Flock_t{
Type: syscall.F_RDLCK,
Start: 0,
Len: 0,
}
if err := syscall.FcntlFlock(f2.Fd(), syscall.F_SETLK, &rlk); err != syscall.EAGAIN {
t.Errorf("FcntlFlock returned %v, expected EAGAIN", err)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment