Conversation
…leaks Co-authored-by: sendya <5404542+sendya@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR addresses file-descriptor leaks in the caching middleware by ensuring storage.File handles opened by getSliceChunkFile are closed on additional error paths within getContents, preventing fd exhaustion under load.
Changes:
- Close the initially opened chunk file when
checkChunkSizefails and the function continues. - Close
chunkFilebefore returning whencheckChunkSizefails in the “anchor chunk” path. - Close
chunkFilebefore returning whengetUpstreamReaderreturns an error.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if err := checkChunkSize(c, chunkFile, idx); err != nil { | ||
| _ = chunkFile.Close() | ||
| _ = c.bucket.Discard(context.Background(), c.id) | ||
| return nil, 0, err | ||
| } |
There was a problem hiding this comment.
checkChunkSize should be called with the chunk index that corresponds to the file being validated. Here chunkFile is opened for availableChunks[index], but idx (the requested starting chunk) is passed instead. This can incorrectly fail validation (notably when the anchor chunk is the last, smaller chunk) and trigger an unnecessary discard. Pass availableChunks[index] to checkChunkSize here.
| @@ -192,6 +193,7 @@ func getContents(c *Caching, reqChunks []uint32, from uint32) (io.ReadCloser, in | |||
| chunkFile, _ := getSliceChunkFile(c, availableChunks[index]) | |||
There was a problem hiding this comment.
The error return from getSliceChunkFile is ignored here (chunkFile, _ := ...). getSliceChunkFile can return non-NotExist errors (including EMFILE via isTooManyFiles), and ignoring it will silently fall back to an upstream fill instead of failing fast. Handle and return the error (similar to the earlier f, err1 := ... branch).
| chunkFile, _ := getSliceChunkFile(c, availableChunks[index]) | |
| chunkFile, err2 := getSliceChunkFile(c, availableChunks[index]) | |
| if err2 != nil { | |
| return nil, 0, err2 | |
| } |
getContentsopensstorage.Filehandles viagetSliceChunkFilebut fails to close them on several error paths, leading to fd exhaustion under load.fwhencheckChunkSizefails instead of falling through with an open handlechunkFilewhencheckChunkSizefails before returning errorchunkFilewhengetUpstreamReaderfails before returning errorOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.