Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

AbsolutePath.ReadKind allocates a new 16 KiB buffer per directory on Windows: the pooled buffer is not returned on failure

Open Beginner friendly
#240 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

@FalconTechDev is already working on this.

Since Oct 19, 2026.

  • #246 by @FalconTechDev — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
csharp
Domain
backend

Research direction

Start with TruePath/DiskUtils.cs, especially TryGetReparseDataBuffer around the ArrayPool<byte>.Shared rent and DeviceIoControl failure return; then trace how AbsolutePath.ReadKind() calls it on Windows. Reproduce the reported allocation with the provided loop and check existing tests for Windows path kinds. Done when ordinary directories reuse or avoid the rented buffer and the allocation drops without changing reparse-point results.

Written by the indexing model from the issue text.

Description

enhancement good first issue help wanted

AbsolutePath.ReadKind() on Windows ends up in DiskUtils.TryGetReparseDataBuffer for every directory. The method rents a 16 KiB buffer from ArrayPool<byte>.Shared, but returns it only on the success path. For anything that isn't a reparse point (i.e. almost every directory), DeviceIoControl(FSCTL_GET_REPARSE_POINT) fails, the method does an early return null, and the rented buffer is dropped. Every call then allocates a fresh 16 KiB array instead of reusing the pooled one.

Measured on ReadKind() (allocated bytes per call):

  • a file: 41 B
  • a directory: 16,480 B

Repro:

var dir = new AbsolutePath(Path.GetTempPath());
for (int i = 0; i < 100; i++) dir.ReadKind(); // warmup
var before = GC.GetAllocatedBytesForCurrentThread();
for (int i = 0; i < 10_000; i++) dir.ReadKind();
Console.WriteLine((GC.GetAllocatedBytesForCurrentThread() - before) / 10_000); // ~16480

This is not a correctness failure, but it defeats the pool and produces a lot of garbage in directory-walking code.

Recommendations

  • Return the buffer on the DeviceIoControl failure path too. DeviceIoControl has finished writing by then, so this is safe (the "abandon rather than return" advice only applies to buffers that might still be in use).
  • Alternatively, rent the buffer only when it is actually needed: ReadKind() already reads the attributes, and a junction always has FileAttributes.ReparsePoint set, so the reparse query can be skipped for everything else. (A 16 KiB stackalloc is not a good replacement for the pool: it is well above the ~1 KB guideline for stack buffers.)
Dominant language
C#
Stars
107
Forks
22
Avg merge
3d 2h
Merged PRs (30d)
13

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ForNeVeR/TruePath

All issues in ForNeVeR/TruePath

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.