mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-13 01:28:37 +02:00
fix(filer): prevent nil pointer dereference in CompactFileChunks when context is cancelled (#11690)
* filer: prevent nil pointer dereference in CompactFileChunks when context is cancelled Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com> * filer: propagate chunk resolution errors through ViewFromChunks A failed manifest resolution produced a nil interval list; with the nil guards this silently became an empty view, so replication sinks would write empty replicas and report success. Return the error so callers fail instead, and make ChunkStreamReader report it on first read. --------- Signed-off-by: Tyagiquamar <mohdquamartyagi@gmail.com> Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com> Co-authored-by: Chris Lu <chris.lu@gmail.com>
This commit is contained in:
2 files changed
+39
No files matched your search
@@ -79,6 +79,9 @@ func CompactFileChunks(ctx context.Context, lookupFileIdFn wdclient.LookupFileId
|
||||
}
|
||||
|
||||
func SeparateGarbageChunks(visibles *IntervalList[*VisibleInterval], chunks []*filer_pb.FileChunk) (compacted []*filer_pb.FileChunk, garbage []*filer_pb.FileChunk) {
|
||||
if visibles == nil {
|
||||
return chunks, nil
|
||||
}
|
||||
fileIds := make(map[string]bool)
|
||||
for x := visibles.Front(); x != nil; x = x.Next {
|
||||
interval := x.Value
|
||||
@@ -225,6 +228,9 @@ func ViewFromVisibleIntervals(visibles *IntervalList[*VisibleInterval], offset i
|
||||
}
|
||||
|
||||
chunkViews = NewIntervalList[*ChunkView]()
|
||||
if visibles == nil {
|
||||
return chunkViews
|
||||
}
|
||||
for x := visibles.Front(); x != nil; x = x.Next {
|
||||
chunk := x.Value
|
||||
|
||||
|
||||
@@ -583,3 +583,36 @@ func TestCompactFileChunks3(t *testing.T) {
|
||||
t.Fatalf("unexpected compacted: %d", len(compacted))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeparateGarbageChunksNilVisibles(t *testing.T) {
|
||||
chunks := []*filer_pb.FileChunk{
|
||||
{Offset: 10, Size: 100, FileId: "abc", ModifiedTsNs: 50},
|
||||
}
|
||||
compacted, garbage := SeparateGarbageChunks(nil, chunks)
|
||||
if len(compacted) != 1 || len(garbage) != 0 {
|
||||
t.Fatalf("expected fallback to original chunks with nil garbage")
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewFromVisibleIntervalsNilVisibles(t *testing.T) {
|
||||
views := ViewFromVisibleIntervals(nil, 0, 100)
|
||||
if views == nil || views.Front() != nil {
|
||||
t.Fatalf("expected empty interval list")
|
||||
}
|
||||
}
|
||||
|
||||
func TestViewFromChunksPropagatesError(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
chunks := []*filer_pb.FileChunk{
|
||||
{Offset: 0, Size: 100, FileId: "abc", ModifiedTsNs: 50, IsChunkManifest: true},
|
||||
}
|
||||
views, err := ViewFromChunks(ctx, nil, chunks, 0, math.MaxInt64)
|
||||
if err == nil {
|
||||
t.Fatal("expected error on cancelled context")
|
||||
}
|
||||
if views != nil {
|
||||
t.Fatalf("expected nil views on error, got %v", views)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user