Skip to content

Fix fd leaks in getContents error paths#45

Open
Copilot wants to merge 2 commits intomainfrom
copilot/fix-fd-leak-in-get-contents
Open

Fix fd leaks in getContents error paths#45
Copilot wants to merge 2 commits intomainfrom
copilot/fix-fd-leak-in-get-contents

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

getContents opens storage.File handles via getSliceChunkFile but fails to close them on several error paths, leading to fd exhaustion under load.

  • Close f when checkChunkSize fails instead of falling through with an open handle
  • Close chunkFile when checkChunkSize fails before returning error
  • Close chunkFile when getUpstreamReader fails before returning error
if f != nil {
    if err := checkChunkSize(c, f, idx); err == nil {
        return f, 1, nil
    }
    _ = f.Close() // was missing
}
Original prompt

This section details on the original issue you should resolve

<issue_title>getSliceChunkFile in function getContents maybe leak fds when return err</issue_title>
<issue_description></issue_description>

Comments on the Issue (you are @copilot in this section)


💡 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.

…leaks

Co-authored-by: sendya <5404542+sendya@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix file descriptor leak in getContents function Fix fd leaks in getContents error paths Mar 3, 2026
@sendya sendya marked this pull request as ready for review March 6, 2026 07:37
Copilot AI review requested due to automatic review settings March 6, 2026 07:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 checkChunkSize fails and the function continues.
  • Close chunkFile before returning when checkChunkSize fails in the “anchor chunk” path.
  • Close chunkFile before returning when getUpstreamReader returns an error.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 195 to 199
if err := checkChunkSize(c, chunkFile, idx); err != nil {
_ = chunkFile.Close()
_ = c.bucket.Discard(context.Background(), c.id)
return nil, 0, err
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
@@ -192,6 +193,7 @@ func getContents(c *Caching, reqChunks []uint32, from uint32) (io.ReadCloser, in
chunkFile, _ := getSliceChunkFile(c, availableChunks[index])
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
chunkFile, _ := getSliceChunkFile(c, availableChunks[index])
chunkFile, err2 := getSliceChunkFile(c, availableChunks[index])
if err2 != nil {
return nil, 0, err2
}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

getSliceChunkFile in function getContents maybe leak fds when return err

3 participants