mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-21 22:12:36 +00: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:
co-authored by
Chris Lu
Chris Lu
parent
cfbfb60817
commit
72da592b27
@@ -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