mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-30 08:50:48 +01:00
mount: refuse to attach opens to a draining file handle (#12219)
* mount: refuse to attach opens to a draining file handle With the writeback cache, releasing the last open of a file leaves the shared FileHandle in the map at counter zero while an async flush drains it; the worker removes the map entries once the flush commits. AcquireHandle waits for a pending flush and then attaches, but the two steps are not atomic: a release can slip in between, drop the counter to zero, and queue the drain while the opener goes on to mint a new file-handle id on the draining handle. When the drain completes, RemoveFileHandle deletes every fh id for the inode -- including the one just minted. The kernel still holds that id, so its next FUSE_READ gets ENOENT from GetHandle; the failed read leaves the folio not uptodate and the kernel surfaces EIO to userspace. This was the flaky TestWritebackCacheConcurrentMixedOps failure. AcquireFileHandle now refuses to attach when the shared handle has reached a zero counter and reports it as draining. AcquireHandle and the Create path retry the whole wait-resolve-attach sequence; the next pass blocks on the pending flush (flag registration and the counter drop share pendingAsyncFlushMu) and builds a fresh handle from the post-flush entry. The DLM-failure release in AcquireHandle also goes through ReleaseHandle so it cannot strand a counter-zero handle outside the drain bookkeeping. Removes the refreshEntryForRead retry from #12206, which worked around the symptom by refetching the entry after the fh id was already gone. Test: TestAcquireFileHandleRefusesDrainingHandle covers the refusal and fresh-handle path; TestWritebackCacheConcurrentMixedOps and an amplified concurrent-overwrite repro run clean. * mount: keep refresh-on-error retry for stale-chunk reads
This commit is contained in:
1 parent
ac7b4f4cf6
commit
fd493f2547
12 files changed
+192
-110
No files matched your search
@@ -57,7 +57,15 @@ func (i *FileHandleToInode) MarkInodeRenamed(inode uint64) {
|
||||
// Every open gets its own fh value over the shared FileHandle so that
|
||||
// RELEASE — which identifies nothing else about the dying description — can
|
||||
// scope per-open state (e.g. OFD lock owners) to the open that is closing.
|
||||
func (i *FileHandleToInode) AcquireFileHandle(wfs *WFS, inode uint64, entry *filer_pb.Entry, versionTsNs int64, signature int32) (*FileHandle, FileHandleId, bool) {
|
||||
//
|
||||
// A handle whose counter already reached zero is draining its deferred flush:
|
||||
// it stays in the map only so rename/unlink can still find it, and
|
||||
// RemoveFileHandle will drop it (and every fh id minted for it) when the drain
|
||||
// completes. Attaching here would hand the kernel an fh id that vanishes mid-
|
||||
// open — reads on it return ENOENT, which the kernel reports to read() as EIO.
|
||||
// Callers must treat a draining report as "wait for the pending flush, then
|
||||
// retry the whole acquire", not as success.
|
||||
func (i *FileHandleToInode) AcquireFileHandle(wfs *WFS, inode uint64, entry *filer_pb.Entry, versionTsNs int64, signature int32) (*FileHandle, FileHandleId, bool, bool) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
fh, found := i.inode2fh[inode]
|
||||
@@ -67,13 +75,16 @@ func (i *FileHandleToInode) AcquireFileHandle(wfs *WFS, inode uint64, entry *fil
|
||||
fh.entryVersionSignature.Store(signature)
|
||||
i.inode2fh[inode] = fh
|
||||
i.fh2inode[fh.fh] = inode
|
||||
return fh, fh.fh, false
|
||||
return fh, fh.fh, false, false
|
||||
}
|
||||
if fh.counter <= 0 {
|
||||
return nil, 0, true, true
|
||||
}
|
||||
fh.counter++
|
||||
openFh := FileHandleId(util.RandomUint64())
|
||||
fh.fhs[openFh] = struct{}{}
|
||||
i.fh2inode[openFh] = inode
|
||||
return fh, openFh, true
|
||||
return fh, openFh, true, false
|
||||
}
|
||||
|
||||
func (i *FileHandleToInode) ReleaseByHandle(fh FileHandleId) *FileHandle {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package mount
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A handle whose last open closed with a deferred flush stays in the map while
|
||||
// the drain runs so rename/unlink can find it. A new open must NOT attach to it:
|
||||
// the fh id it would mint is dropped by RemoveFileHandle, leaving kernel reads
|
||||
// to fail with ENOENT — which the kernel reports to read() as EIO.
|
||||
func TestAcquireFileHandleRefusesDrainingHandle(t *testing.T) {
|
||||
wfs := &WFS{option: &Option{}}
|
||||
fhMap := NewFileHandleToInode()
|
||||
inode := uint64(12345)
|
||||
|
||||
fh, _, existed, draining := fhMap.AcquireFileHandle(wfs, inode, nil, 0, 0)
|
||||
if existed || draining || fh == nil {
|
||||
t.Fatalf("first acquire: fh=%v existed=%v draining=%v", fh, existed, draining)
|
||||
}
|
||||
fh.asyncFlushPending = true
|
||||
|
||||
// Last release with a deferred flush keeps the draining handle in the map.
|
||||
released := fhMap.ReleaseByHandle(fh.fh)
|
||||
if released != fh {
|
||||
t.Fatalf("ReleaseByHandle returned %v, want the draining handle", released)
|
||||
}
|
||||
if _, found := fhMap.FindFileHandle(inode); !found {
|
||||
t.Fatal("draining handle should stay in the map for rename/unlink")
|
||||
}
|
||||
|
||||
// A new open must not resurrect the draining handle.
|
||||
fh2, openFh, existed, draining := fhMap.AcquireFileHandle(wfs, inode, nil, 0, 0)
|
||||
if !draining || fh2 != nil {
|
||||
t.Fatalf("acquire during drain: fh=%v openFh=%v existed=%v draining=%v, want draining", fh2, openFh, existed, draining)
|
||||
}
|
||||
|
||||
// After the drain removes the handle, the next acquire creates a fresh one.
|
||||
fhMap.RemoveFileHandle(fh.fh, inode)
|
||||
fh3, _, existed, draining := fhMap.AcquireFileHandle(wfs, inode, nil, 0, 0)
|
||||
if draining || existed || fh3 == nil || fh3 == fh {
|
||||
t.Fatalf("acquire after drain: fh=%v existed=%v draining=%v, want fresh handle", fh3, existed, draining)
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ func TestReadUncachedRemoteEntryDoesNotDeadlock(t *testing.T) {
|
||||
t.Cleanup(func() { wfs.metaCache.Shutdown() })
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: uint64(len(testServer.content))},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: int64(len(testServer.content))},
|
||||
|
||||
@@ -21,7 +21,7 @@ func TestWholeFileServerCopyCandidate(t *testing.T) {
|
||||
srcInode := wfs.inodeToPath.Lookup(srcPath, 1, false, false, 0, true)
|
||||
dstInode := wfs.inodeToPath.Lookup(dstPath, 1, false, false, 0, true)
|
||||
|
||||
srcHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
srcHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
Name: "src.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -30,7 +30,7 @@ func TestWholeFileServerCopyCandidate(t *testing.T) {
|
||||
},
|
||||
Content: []byte("hello"),
|
||||
}, 0, 0)
|
||||
dstHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
dstHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
Name: "dst.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -86,7 +86,7 @@ func TestCopyFileRangeUsesServerSideWholeFileCopy(t *testing.T) {
|
||||
srcInode := wfs.inodeToPath.Lookup(srcPath, 1, false, false, 0, true)
|
||||
dstInode := wfs.inodeToPath.Lookup(dstPath, 1, false, false, 0, true)
|
||||
|
||||
srcHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
srcHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
Name: "src.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -95,7 +95,7 @@ func TestCopyFileRangeUsesServerSideWholeFileCopy(t *testing.T) {
|
||||
},
|
||||
Content: []byte("hello"),
|
||||
}, 0, 0)
|
||||
dstHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
dstHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
Name: "dst.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -171,7 +171,7 @@ func TestCopyFileRangeDoesNotFallbackAfterCommittedServerCopyRefreshFailure(t *t
|
||||
srcInode := wfs.inodeToPath.Lookup(srcPath, 1, false, false, 0, true)
|
||||
dstInode := wfs.inodeToPath.Lookup(dstPath, 1, false, false, 0, true)
|
||||
|
||||
srcHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
srcHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
Name: "src.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -182,7 +182,7 @@ func TestCopyFileRangeDoesNotFallbackAfterCommittedServerCopyRefreshFailure(t *t
|
||||
},
|
||||
Content: []byte("hello"),
|
||||
}, 0, 0)
|
||||
dstHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
dstHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
Name: "dst.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100600,
|
||||
@@ -253,7 +253,7 @@ func TestCopyFileRangeReturnsEIOForAmbiguousServerSideCopy(t *testing.T) {
|
||||
srcInode := wfs.inodeToPath.Lookup(srcPath, 1, false, false, 0, true)
|
||||
dstInode := wfs.inodeToPath.Lookup(dstPath, 1, false, false, 0, true)
|
||||
|
||||
srcHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
srcHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
Name: "src.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
@@ -262,7 +262,7 @@ func TestCopyFileRangeReturnsEIOForAmbiguousServerSideCopy(t *testing.T) {
|
||||
},
|
||||
Content: []byte("hello"),
|
||||
}, 0, 0)
|
||||
dstHandle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
dstHandle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
Name: "dst.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100600,
|
||||
|
||||
@@ -22,7 +22,7 @@ func newOpenFileHandle(t *testing.T, fileSize uint64) (*WFS, *FileHandle) {
|
||||
wfs := newCopyRangeTestWFS()
|
||||
path := util.FullPath("/file.txt")
|
||||
inode := wfs.inodeToPath.Lookup(path, 1, false, false, 0, true)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
|
||||
@@ -132,7 +132,20 @@ func (wfs *WFS) Create(cancel <-chan struct{}, in *fuse.CreateIn, name string, o
|
||||
// For deferred creates, bypass AcquireHandle (which calls maybeReadEntry
|
||||
// and would fail since the entry is not yet on the filer or in the meta cache).
|
||||
// We already have the entry from createRegularFile, so create the handle directly.
|
||||
fileHandle, openFh, existed := wfs.fhMap.AcquireFileHandle(wfs, inode, newEntry, 0, 0)
|
||||
var fileHandle *FileHandle
|
||||
var openFh FileHandleId
|
||||
var existed, draining bool
|
||||
for {
|
||||
fileHandle, openFh, existed, draining = wfs.fhMap.AcquireFileHandle(wfs, inode, newEntry, 0, 0)
|
||||
if !draining {
|
||||
break
|
||||
}
|
||||
// A prior incarnation's deferred flush is still draining on this
|
||||
// inode; wait for it to release the handle before attaching ours.
|
||||
if !wfs.waitForPendingAsyncFlush(ctx, inode) {
|
||||
return fuse.EINTR
|
||||
}
|
||||
}
|
||||
if existed {
|
||||
// A create is authoritative for the entry it just made, so it takes
|
||||
// effect even on a handle that outlived a previous incarnation.
|
||||
|
||||
@@ -267,7 +267,7 @@ func TestTruncateEntryClearsDirtyPagesForOpenHandle(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
fh.RememberPath(fullPath)
|
||||
|
||||
if err := fh.dirtyPages.AddPage(0, []byte("hello"), true, time.Now().UnixNano()); err != nil {
|
||||
@@ -315,7 +315,7 @@ func TestAccessChecksPermissions(t *testing.T) {
|
||||
|
||||
fullPath := util.FullPath("/visible.txt")
|
||||
inode := wfs.inodeToPath.Lookup(fullPath, 1, false, false, 0, true)
|
||||
handle, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
handle, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "visible.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0o640,
|
||||
|
||||
@@ -9,69 +9,84 @@ import (
|
||||
"github.com/seaweedfs/seaweedfs/weed/cluster/lock_manager"
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
)
|
||||
|
||||
// AcquireHandle returns the shared handle for inode plus this open's own fh
|
||||
// value — the id handed to the kernel and seen again at RELEASE.
|
||||
func (wfs *WFS) AcquireHandle(ctx context.Context, inode uint64, flags, uid, gid uint32) (fileHandle *FileHandle, openFh FileHandleId, status fuse.Status) {
|
||||
// If there is an in-flight async flush for this inode, wait for it to
|
||||
// complete before reopening. Otherwise the new handle would be built
|
||||
// from pre-close filer metadata and its next flush could overwrite the
|
||||
// data that was just written asynchronously.
|
||||
if !wfs.waitForPendingAsyncFlush(ctx, inode) {
|
||||
return nil, 0, fuse.EINTR
|
||||
}
|
||||
var path util.FullPath
|
||||
for {
|
||||
// If there is an in-flight async flush for this inode, wait for it to
|
||||
// complete before reopening. Otherwise the new handle would be built
|
||||
// from pre-close filer metadata and its next flush could overwrite the
|
||||
// data that was just written asynchronously.
|
||||
if !wfs.waitForPendingAsyncFlush(ctx, inode) {
|
||||
return nil, 0, fuse.EINTR
|
||||
}
|
||||
|
||||
path, pathStatus := wfs.inodeToPath.GetPath(inode)
|
||||
if pathStatus != fuse.OK {
|
||||
return nil, 0, pathStatus
|
||||
}
|
||||
var pathStatus fuse.Status
|
||||
path, pathStatus = wfs.inodeToPath.GetPath(inode)
|
||||
if pathStatus != fuse.OK {
|
||||
return nil, 0, pathStatus
|
||||
}
|
||||
|
||||
// A fresh lookup returns the entry with the filer log position it
|
||||
// reflects; the handle takes that entry and version as one decision in
|
||||
// AcquireFileHandle, so a slower concurrent opener cannot
|
||||
// overwrite a newer install. An existing handle keeps its own entry and
|
||||
// version — they did not come from this lookup.
|
||||
var entry *filer_pb.Entry
|
||||
var entryVersionTsNs entryVersion
|
||||
freshLookup := false
|
||||
if existingFh, found := wfs.fhMap.FindFileHandle(inode); found {
|
||||
entry = existingFh.UpdateEntry(func(entry *filer_pb.Entry) {
|
||||
if entry != nil && existingFh.entry.Attributes == nil {
|
||||
entry.Attributes = &filer_pb.FuseAttributes{}
|
||||
// A fresh lookup returns the entry with the filer log position it
|
||||
// reflects; the handle takes that entry and version as one decision in
|
||||
// AcquireFileHandle, so a slower concurrent opener cannot
|
||||
// overwrite a newer install. An existing handle keeps its own entry and
|
||||
// version — they did not come from this lookup.
|
||||
var entry *filer_pb.Entry
|
||||
var entryVersionTsNs entryVersion
|
||||
freshLookup := false
|
||||
if existingFh, found := wfs.fhMap.FindFileHandle(inode); found {
|
||||
entry = existingFh.UpdateEntry(func(entry *filer_pb.Entry) {
|
||||
if entry != nil && existingFh.entry.Attributes == nil {
|
||||
entry.Attributes = &filer_pb.FuseAttributes{}
|
||||
}
|
||||
})
|
||||
entryVersionTsNs = entryVersion{tsNs: existingFh.entryVersionTsNs.Load(), signature: existingFh.entryVersionSignature.Load()}
|
||||
} else {
|
||||
entry, entryVersionTsNs, status = wfs.maybeLoadEntry(ctx, path)
|
||||
if status != fuse.OK {
|
||||
return nil, 0, status
|
||||
}
|
||||
})
|
||||
entryVersionTsNs = entryVersion{tsNs: existingFh.entryVersionTsNs.Load(), signature: existingFh.entryVersionSignature.Load()}
|
||||
} else {
|
||||
entry, entryVersionTsNs, status = wfs.maybeLoadEntry(ctx, path)
|
||||
if status != fuse.OK {
|
||||
return nil, 0, status
|
||||
freshLookup = true
|
||||
}
|
||||
freshLookup = true
|
||||
}
|
||||
if wormEnforced, _ := wfs.wormEnforcedForEntry(path, entry); wormEnforced && flags&fuse.O_ANYWRITE != 0 {
|
||||
return nil, 0, fuse.EPERM
|
||||
}
|
||||
// Check unix permission bits for the requested access mode. With
|
||||
// default_permissions the kernel already enforced them before this
|
||||
// open, so the check (and its supplementary-group lookup) is redundant.
|
||||
if !wfs.option.DefaultPermissions && entry != nil && entry.Attributes != nil {
|
||||
fileUid, fileGid := entry.Attributes.Uid, entry.Attributes.Gid
|
||||
if wfs.option.UidGidMapper != nil {
|
||||
fileUid, fileGid = wfs.option.UidGidMapper.FilerToLocal(fileUid, fileGid)
|
||||
if wormEnforced, _ := wfs.wormEnforcedForEntry(path, entry); wormEnforced && flags&fuse.O_ANYWRITE != 0 {
|
||||
return nil, 0, fuse.EPERM
|
||||
}
|
||||
if mask := openFlagsToAccessMask(flags); mask != 0 && !hasAccess(uid, gid, fileUid, fileGid, entry.Attributes.FileMode, mask) {
|
||||
return nil, 0, fuse.EACCES
|
||||
// Check unix permission bits for the requested access mode. With
|
||||
// default_permissions the kernel already enforced them before this
|
||||
// open, so the check (and its supplementary-group lookup) is redundant.
|
||||
if !wfs.option.DefaultPermissions && entry != nil && entry.Attributes != nil {
|
||||
fileUid, fileGid := entry.Attributes.Uid, entry.Attributes.Gid
|
||||
if wfs.option.UidGidMapper != nil {
|
||||
fileUid, fileGid = wfs.option.UidGidMapper.FilerToLocal(fileUid, fileGid)
|
||||
}
|
||||
if mask := openFlagsToAccessMask(flags); mask != 0 && !hasAccess(uid, gid, fileUid, fileGid, entry.Attributes.FileMode, mask) {
|
||||
return nil, 0, fuse.EACCES
|
||||
}
|
||||
}
|
||||
}
|
||||
// need to AcquireFileHandle again to ensure correct handle counter
|
||||
var existed bool
|
||||
fileHandle, openFh, existed = wfs.fhMap.AcquireFileHandle(wfs, inode, entry, entryVersionTsNs.tsNs, entryVersionTsNs.signature)
|
||||
fileHandle.RememberPath(path)
|
||||
if existed && freshLookup {
|
||||
// Another opener created the handle while our lookup was in flight;
|
||||
// install only state that provably improves on what it holds.
|
||||
fileHandle.installAckedEntry(entry, entryVersionTsNs.tsNs, entryVersionTsNs.signature)
|
||||
// need to AcquireFileHandle again to ensure correct handle counter
|
||||
var existed, draining bool
|
||||
fileHandle, openFh, existed, draining = wfs.fhMap.AcquireFileHandle(wfs, inode, entry, entryVersionTsNs.tsNs, entryVersionTsNs.signature)
|
||||
if draining {
|
||||
// A RELEASE slipped between waitForPendingAsyncFlush and this
|
||||
// attach: the handle's last open closed and its deferred flush
|
||||
// is draining. The pending-flush flag is registered under the
|
||||
// same mutex that dropped the counter, so the next iteration
|
||||
// blocks on the drain (or finds the handle already removed)
|
||||
// and rebuilds state from post-flush metadata.
|
||||
continue
|
||||
}
|
||||
fileHandle.RememberPath(path)
|
||||
if existed && freshLookup {
|
||||
// Another opener created the handle while our lookup was in flight;
|
||||
// install only state that provably improves on what it holds.
|
||||
fileHandle.installAckedEntry(entry, entryVersionTsNs.tsNs, entryVersionTsNs.signature)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// Acquire distributed lock for write opens. The lock is held with
|
||||
@@ -86,7 +101,7 @@ func (wfs *WFS) AcquireHandle(ctx context.Context, inode uint64, flags, uid, gid
|
||||
if fileHandle.dlmLock == nil {
|
||||
// No lock server is reachable: proceeding would silently drop
|
||||
// cross-mount write serialization, so fail the open instead.
|
||||
wfs.fhMap.ReleaseByHandle(openFh)
|
||||
wfs.ReleaseHandle(openFh)
|
||||
return nil, 0, fuse.Status(syscall.EAGAIN)
|
||||
}
|
||||
glog.V(1).Infof("DLM lock acquired for %s", path)
|
||||
|
||||
@@ -195,7 +195,7 @@ func TestUpdateEventRefreshesOpenFileHandle(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -260,7 +260,7 @@ func TestQueuedEventDoesNotRollBackNewerLocalState(t *testing.T) {
|
||||
wfs.inodeToPath.MarkChildrenCached(util.FullPath("/dir"))
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -302,7 +302,7 @@ func TestBufferedBuildEventReinvalidatesOnCompletion(t *testing.T) {
|
||||
wfs.inodeToPath.Lookup(util.FullPath("/dir"), time.Now().Unix(), true, false, 0, false)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -352,7 +352,7 @@ func TestUncachedDirStaleStoreEntryDoesNotMaskEvent(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -388,7 +388,7 @@ func TestQueuedEventOlderThanFlushedStateIsIgnored(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -424,7 +424,7 @@ func TestSaveEntryKeepsOpenHandleAheadOfOlderEvents(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -462,7 +462,7 @@ func TestQueuedEventDoesNotRollBackHandleOpenedAfterEnqueue(t *testing.T) {
|
||||
// Stall the single invalidation worker on an unrelated handle's lock so
|
||||
// queued events outlive the open below.
|
||||
blockerInode := wfs.inodeToPath.Lookup(util.FullPath("/other/blocker"), time.Now().Unix(), false, false, 0, false)
|
||||
blockerFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
blockerFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
Name: "blocker",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 1},
|
||||
}, 0, 0)
|
||||
@@ -523,7 +523,7 @@ func TestAbortedBuildEventDoesNotRollBackLaterOpen(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{lookupSize: 200, lookupLogTsNs: 2000})
|
||||
|
||||
blockerInode := wfs.inodeToPath.Lookup(util.FullPath("/other/blocker"), time.Now().Unix(), false, false, 0, false)
|
||||
blockerFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
blockerFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
Name: "blocker",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 1},
|
||||
}, 0, 0)
|
||||
@@ -590,7 +590,7 @@ func TestEventDuringOpenLookupIsFenced(t *testing.T) {
|
||||
startFakeFiler(t, wfs, fake)
|
||||
|
||||
blockerInode := wfs.inodeToPath.Lookup(util.FullPath("/other/blocker"), time.Now().Unix(), false, false, 0, false)
|
||||
blockerFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
blockerFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, blockerInode, &filer_pb.Entry{
|
||||
Name: "blocker",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 1},
|
||||
}, 0, 0)
|
||||
@@ -667,7 +667,7 @@ func TestRemoteCacheResponseVersionFencesUndeliveredEvents(t *testing.T) {
|
||||
}
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -699,7 +699,7 @@ func TestEventlessSaveAckStillFencesOlderEvents(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{updateEventless: true, updateLogTsNs: 2000})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -884,7 +884,7 @@ func TestAlreadyReflectedEventDoesNotDestroyDirtyPages(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -998,7 +998,7 @@ func TestAlreadyReflectedEventPreservesDirtyWrites(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -1077,7 +1077,7 @@ func TestServerSideCopyInstallEnrollsInBase(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
}, 0, 0)
|
||||
@@ -1198,7 +1198,7 @@ func TestCommittedCopyWithFailedReadbackAdoptsItsEvent(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
}, 0, 0)
|
||||
@@ -1311,7 +1311,7 @@ func TestFlushAckCancelsPendingCopyEventAdoption(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
}, 0, 0)
|
||||
@@ -1356,7 +1356,7 @@ func TestAckedSaveInstallsIntoRacingOpenHandle(t *testing.T) {
|
||||
|
||||
// The handle opened after the setattr path found none, before the ack.
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -1378,7 +1378,7 @@ func TestAckedSaveInstallsIntoRacingOpenHandle(t *testing.T) {
|
||||
|
||||
// A dirty handle is left alone entirely: neither entry nor version.
|
||||
dirtyInode := wfs.inodeToPath.Lookup(util.FullPath("/dir/dirty"), time.Now().Unix(), false, false, 0, false)
|
||||
dirtyFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dirtyInode, &filer_pb.Entry{
|
||||
dirtyFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dirtyInode, &filer_pb.Entry{
|
||||
Name: "dirty",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -1434,7 +1434,7 @@ func TestVacateEventPreservesDirtyPages(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -1469,7 +1469,7 @@ func TestCopyAdoptRejectsForeignEvent(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
}, 0, 0)
|
||||
@@ -1500,7 +1500,7 @@ func TestRemoteDownloadBaseMappedToLocal(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{cacheSize: 200, cacheUid: 2000, cacheLogTsNs: 1000})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: 200},
|
||||
@@ -1545,7 +1545,7 @@ func TestForeignDeleteMarksHandleDeleted(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -1603,7 +1603,7 @@ func TestStaleRemoteDownloadDoesNotRollBack(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{cacheSize: 100, cacheLogTsNs: 1000})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: 200},
|
||||
@@ -1637,7 +1637,7 @@ func TestRemoteOnlyHandleTakesUnversionedDownload(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{cacheSize: 100})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: 100},
|
||||
@@ -1662,7 +1662,7 @@ func TestCopyAdoptRejectsForeignMetadataChange(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200, FileMode: 0100644},
|
||||
}, 0, 0)
|
||||
@@ -1697,7 +1697,7 @@ func TestForeignRenameDoesNotMarkHandleDeleted(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
}, 0, 0)
|
||||
@@ -1752,7 +1752,7 @@ func TestCopyAdoptAppliesForeignTouchToCleanHandle(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200, Mtime: 100},
|
||||
}, 0, 0)
|
||||
@@ -1788,7 +1788,7 @@ func TestUnversionedRemoteDownloadDoesNotOverwriteVersioned(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{cacheSize: 100})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: 200},
|
||||
@@ -1860,7 +1860,7 @@ func TestTouchBeforeCopyEventKeepsPostCopyWrites(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100, Mtime: 100},
|
||||
}, 0, 0)
|
||||
@@ -1924,7 +1924,7 @@ func TestRejectedDownloadDoesNotRollBackCache(t *testing.T) {
|
||||
wfs.metaCache.WaitForEntryInvalidations()
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
Chunks: []*filer_pb.FileChunk{{FileId: "1,ab1", Size: 200}},
|
||||
@@ -1959,7 +1959,7 @@ func TestRemoteOnlyHandleRefusesKnownOlderDownload(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{cacheSize: 100, cacheLogTsNs: 1000})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200},
|
||||
RemoteEntry: &filer_pb.RemoteEntry{RemoteSize: 200},
|
||||
@@ -1981,7 +1981,7 @@ func TestForeignChmodPreservesDirtyPages(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 200, FileMode: 0100644},
|
||||
}, 0, 0)
|
||||
@@ -2013,12 +2013,12 @@ func TestRenameOverExistingMarksReplacedHandleDeleted(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
srcInode := wfs.inodeToPath.Lookup(util.FullPath("/dir/src"), time.Now().Unix(), false, false, 0, false)
|
||||
srcFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
srcFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, srcInode, &filer_pb.Entry{
|
||||
Name: "src",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 100},
|
||||
}, 0, 0)
|
||||
dstInode := wfs.inodeToPath.Lookup(util.FullPath("/dir/dst"), time.Now().Unix(), false, false, 0, false)
|
||||
dstFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
dstFh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, dstInode, &filer_pb.Entry{
|
||||
Name: "dst",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 900},
|
||||
}, 0, 0)
|
||||
@@ -2053,7 +2053,7 @@ func TestAckFromAnotherFilerIsNotDroppedBehindForeignFence(t *testing.T) {
|
||||
wfs := newInvalidateTestWFS(t)
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/file"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestReleaseDropsFlockWhileFlushBlocked(t *testing.T) {
|
||||
startFakeFiler(t, wfs, &fakeFilerServer{})
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(util.FullPath("/dir/f"), time.Now().Unix(), false, false, 0, false)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "f",
|
||||
Attributes: &filer_pb.FuseAttributes{},
|
||||
}, 0, 0)
|
||||
@@ -91,8 +91,8 @@ func TestReleaseDropsOfdLocks(t *testing.T) {
|
||||
Name: "f",
|
||||
Attributes: &filer_pb.FuseAttributes{},
|
||||
}
|
||||
_, openFh, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
_, siblingFh, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
_, openFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
_, siblingFh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, entry, 0, 0)
|
||||
if siblingFh == openFh {
|
||||
t.Fatal("sibling open must get its own fh value")
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func TestRemoteRenameReplayLeavesTheTargetAlone(t *testing.T) {
|
||||
oldPath, newPath := util.FullPath("/dir/file"), util.FullPath("/dir/renamed")
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(oldPath, time.Now().Unix(), false, false, 0, true)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
@@ -100,7 +100,7 @@ func TestRenameBelowTheVersionFenceStillMoves(t *testing.T) {
|
||||
oldPath, newPath := util.FullPath("/dir/file"), util.FullPath("/dir/renamed")
|
||||
|
||||
inode := wfs.inodeToPath.Lookup(oldPath, time.Now().Unix(), false, false, 0, true)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "file",
|
||||
Attributes: &filer_pb.FuseAttributes{FileSize: 88},
|
||||
}, 0, 0)
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestSetXAttrCopiesValueBuffer(t *testing.T) {
|
||||
|
||||
path := util.FullPath("/aaa.txt")
|
||||
inode := wfs.inodeToPath.Lookup(path, 1, false, false, 0, true)
|
||||
fh, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
fh, _, _, _ := wfs.fhMap.AcquireFileHandle(wfs, inode, &filer_pb.Entry{
|
||||
Name: "aaa.txt",
|
||||
Attributes: &filer_pb.FuseAttributes{
|
||||
FileMode: 0100644,
|
||||
|
||||
Reference in new issue
Block a user