mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-17 19:48:35 +02:00
filer: compare IF_ENTRY_EQUAL against the normalized expected entry
FindEntry grows FileSize to the chunk extent, so a raw event entry with FileSize still zero failed the condition on an unchanged file and the stamp was skipped, letting a replay upload the object again.
This commit is contained in:
1 parent
92bd112cfd
commit
8cc3e299fc
2 files changed
+34
-3
No files matched your search
@@ -84,10 +84,13 @@ func clauseSatisfied(c *filer_pb.WriteCondition_Clause, current *filer.Entry) bo
|
||||
case filer_pb.WriteCondition_IF_CHUNKS_EQUAL:
|
||||
return chunkFidsEqual(current, c.Fids)
|
||||
case filer_pb.WriteCondition_IF_ENTRY_EQUAL:
|
||||
if !exists {
|
||||
return c.ExpectedEntry == nil
|
||||
if !exists || c.ExpectedEntry == nil {
|
||||
return !exists && c.ExpectedEntry == nil
|
||||
}
|
||||
return proto.Equal(current.ToProtoEntry(), c.ExpectedEntry)
|
||||
// Normalize the expected entry the way FindEntry normalizes the stored
|
||||
// one (e.g. FileSize grows to the chunk extent), or an unchanged entry
|
||||
// can compare unequal.
|
||||
return proto.Equal(current.ToProtoEntry(), filer.FromPbEntry("", c.ExpectedEntry).ToProtoEntry())
|
||||
default:
|
||||
// An unrecognized clause kind (e.g. from a newer client) must not be
|
||||
// treated as satisfied, which would silently bypass the guard. Fail
|
||||
|
||||
@@ -193,6 +193,34 @@ func TestWriteConditionUnknownKindFailsClosed(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// IF_ENTRY_EQUAL compares the expected entry after the same normalization
|
||||
// FindEntry applied to the stored one: a raw event entry whose FileSize is
|
||||
// still zero must match a stored entry grown to its chunk extent.
|
||||
func TestIfEntryEqualNormalizesExpected(t *testing.T) {
|
||||
raw := &filer_pb.Entry{
|
||||
Name: "f",
|
||||
Attributes: &filer_pb.FuseAttributes{Mtime: 42},
|
||||
Chunks: []*filer_pb.FileChunk{
|
||||
{Fid: &filer_pb.FileId{VolumeId: 3, FileKey: 1, Cookie: 2}, Size: 100},
|
||||
},
|
||||
}
|
||||
stored := filer.FromPbEntry("/d", raw)
|
||||
if stored.FileSize != 100 {
|
||||
t.Fatalf("stored FileSize = %d, want chunk extent 100", stored.FileSize)
|
||||
}
|
||||
cond := one(&filer_pb.WriteCondition_Clause{
|
||||
Kind: filer_pb.WriteCondition_IF_ENTRY_EQUAL,
|
||||
ExpectedEntry: raw,
|
||||
})
|
||||
if !writeConditionSatisfied(cond, stored) {
|
||||
t.Error("raw expected entry must equal its normalized stored form")
|
||||
}
|
||||
raw.Attributes.Mtime = 43
|
||||
if writeConditionSatisfied(cond, stored) {
|
||||
t.Error("changed expected entry must not equal the stored entry")
|
||||
}
|
||||
}
|
||||
|
||||
// storedEntryETag prefers the stored Seaweed ETag attribute and falls back to
|
||||
// the Md5-derived ETag, matching the S3 gateway.
|
||||
func TestStoredEntryETag(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user