From 2441d038e528242dde19547406018d0f81b2b7eb Mon Sep 17 00:00:00 2001 From: Sandy Xu Date: Thu, 12 Sep 2024 14:36:33 +0800 Subject: [PATCH] meta: in compaction don't skip the first slice if it's duplicated (#5159) --- pkg/meta/base_test.go | 15 +++++++++++++++ pkg/meta/slice.go | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/pkg/meta/base_test.go b/pkg/meta/base_test.go index 4cd96fc3630d..4bc4fdda5e27 100644 --- a/pkg/meta/base_test.go +++ b/pkg/meta/base_test.go @@ -1324,6 +1324,21 @@ func testCompaction(t *testing.T, m Meta, trash bool) { t.Fatalf("inode %d should be compacted, but have %d slices, size %d,%d,%d", inode, len(slices), slices[0].Len, slices[1].Len, slices[2].Len) } + + m.NewSlice(ctx, &sliceId) + _ = m.Write(ctx, inode, 3, 0, Slice{Id: sliceId, Size: 2338508, Len: 2338508}, time.Now()) + _ = m.CopyFileRange(ctx, inode, 3*ChunkSize, inode, 4*ChunkSize, 2338508, 0, nil, nil) + _ = m.Fallocate(ctx, inode, fallocZeroRange, 4*ChunkSize, ChunkSize, nil) + _ = m.CopyFileRange(ctx, inode, 3*ChunkSize, inode, 4*ChunkSize, 2338508, 0, nil, nil) + if c, ok := m.(compactor); ok { + c.compactChunk(inode, 4, false, true) + } + if st := m.Read(ctx, inode, 4, &slices); st != 0 { + t.Fatalf("read inode %d chunk 4: %s", inode, st) + } + if len(slices) != 1 || slices[0].Len != 2338508 { + t.Fatalf("inode %d should be compacted, but have %d slices, size %d", inode, len(slices), slices[0].Len) + } } func testConcurrentWrite(t *testing.T, m Meta) { diff --git a/pkg/meta/slice.go b/pkg/meta/slice.go index d036954dba80..08bdda4c63a6 100644 --- a/pkg/meta/slice.go +++ b/pkg/meta/slice.go @@ -174,6 +174,7 @@ func compactChunk(ss []*slice) (uint32, uint32, []Slice) { func skipSome(chunk []*slice) int { var skipped int var total = len(chunk) +OUT: for skipped < total { ss := chunk[skipped:] pos, size, c := compactChunk(ss) @@ -189,6 +190,11 @@ func skipSome(chunk []*slice) int { // it's not the first slice, compact it break } + for _, s := range ss[1:] { + if *s == *first { + break OUT + } + } skipped++ } return skipped