diff --git a/weed/filer/filer.go b/weed/filer/filer.go index 3b2531d059..c93b9045f7 100644 --- a/weed/filer/filer.go +++ b/weed/filer/filer.go @@ -525,10 +525,10 @@ func (f *Filer) CreateEntry(ctx context.Context, entry *Entry, existing *Entry, if oldEntry == nil { var findErr error // A lazy fetch here would persist outside the transaction and wait on - // the lock it holds for a target it just deleted; the create writes - // the path either way. + // the lock it holds for a target it just deleted; a non-exclusive + // create writes the path either way. findCtx := ctx - if ctx.Value(storeTransactionKey{}) != nil { + if ctx.Value(storeTransactionKey{}) != nil && !o_excl { findCtx = context.WithValue(ctx, lazyFetchContextKey{}, true) } oldEntry, findErr = f.FindEntry(findCtx, entry.FullPath) diff --git a/weed/filer/filer_lazy_remote_test.go b/weed/filer/filer_lazy_remote_test.go index 48e0101859..e5dca2bd5b 100644 --- a/weed/filer/filer_lazy_remote_test.go +++ b/weed/filer/filer_lazy_remote_test.go @@ -763,6 +763,11 @@ func TestCreateEntry_SkipsTheLazyFetchInsideAStoreTransaction(t *testing.T) { require.NotNil(t, entry) assert.True(t, entry.IsInRemoteOnly()) assert.NotZero(t, countingStub.statCalls) + + // an exclusive create inside the transaction still sees the remote object + excl := &Entry{FullPath: "/buckets/mybucket/dir/c.txt", Attr: Attr{Mode: 0644, Mtime: time.Now(), Crtime: time.Now()}} + err = f.CreateEntry(txCtx, excl, nil, true, false, nil, false, f.MaxFilenameLength) + assert.ErrorIs(t, err, filer_pb.ErrEntryAlreadyExists) } func TestMaybeLazyFetchFromRemote_GuardedClientRejectsEndpoint(t *testing.T) {