Skip to content

localfs: Amend Readdir compliance - #101

Open
djdv wants to merge 4 commits into
hugelgupf:mainfrom
djdv:J/readdir-compliance
Open

localfs: Amend Readdir compliance#101
djdv wants to merge 4 commits into
hugelgupf:mainfrom
djdv:J/readdir-compliance

Conversation

@djdv

@djdv djdv commented Dec 20, 2025

Copy link
Copy Markdown
Collaborator

Resolves: #100

Seems to work correctly, but this might sit around for a while as I continue to test and look at it again.
Feel free to also test and review it while it's still a draft.
Eventually, I'll switch it over to final, and set a merge deadline afterwards.


This also adds 2 new exposed method:
DirentSize and ReadDir.

We'll have to decide if these are worth adding to the public API, and what they should be named + how they should work.
ReadDir is probably sensible, but there's a remark in there about how I normally implement these in calling code that might be a good pattern for this as well.

This part of the PR could probably be separated out while we retain the fixes to Local.Readdir.

djdv added 4 commits December 20, 2025 16:27
`DirentSize` helps calculate the `count` parameter for `File.Readdir`.
`ReadDir` performs a full read on a `File`.
Both work fine as-is but the API should not be considered stable yet.
The count parameter for `Readdir` is a byte count (as in POSIX
`getdents`), not an integral count (as in Go).
This patch treats the value as such, and does estimates and conversions
from 9P -> Go to perform the operations within the expectations of the
9P standard.
Excess entries read during operation, are retained on the FID, to allow
subsequent calls to resume reading the directory with the appropriate
offset.
Rewinding the directory is also supported with offset `0`.
Works but is not considered stable yet.
@codecov

codecov Bot commented Dec 20, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.28986% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.94%. Comparing base (abc96d2) to head (a96bbb8).
⚠️ Report is 14 commits behind head on main.

Files with missing lines Patch % Lines
fsimpl/localfs/readdir.go 61.85% 26 Missing and 11 partials ⚠️
fsimpl/test/filetest.go 60.00% 1 Missing and 1 partial ⚠️
p9/p9.go 94.44% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #101      +/-   ##
==========================================
+ Coverage   58.50%   61.94%   +3.43%     
==========================================
  Files          37       37              
  Lines        4779     3939     -840     
==========================================
- Hits         2796     2440     -356     
+ Misses       1776     1283     -493     
- Partials      207      216       +9     
Flag Coverage Δ
macos-latest-unit 46.96% <70.28%> (+4.37%) ⬆️
ubuntu-latest-unit 46.07% <70.28%> (+4.25%) ⬆️
ubuntu-vm-amd64 62.09% <70.28%> (+3.45%) ⬆️
ubuntu-vm-arm 60.59% <70.28%> (+3.72%) ⬆️
ubuntu-vm-arm64 60.59% <70.28%> (+3.82%) ⬆️
windows-latest-unit 47.28% <70.28%> (+4.33%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread fsimpl/localfs/readdir.go
Comment on lines +18 to +26
const (
qidSize = 13 // qid[13]
offsetSize = 8 // offset[8]
typeSize = 1 // type[1]
sringHeaderSize = 2 // length prefix for name[s]
minDirentSize = qidSize + offsetSize +
typeSize + sringHeaderSize
minimumNameLen = 1
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These constants overlap with the ones in p9's direntSize. This should be cleaned up somehow.
Maybe we expose a constant p9.MinimumEntry that callers can reference in addition to just p9.DirentSize? Maybe some other way?

Comment thread fsimpl/localfs/readdir.go

func (l *Local) getChunkSize(offset uint64, count uint32) (int, error) {
if offset == 0 {
return 1, nil // "Peek" is a common enough request.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I doubt my own comment here. Real heuristics to back|disprove this would be better.
How common is it for programmers to request a single entry from a directory?
And is this typically implemented as a special fast-case for any file systems?
Would it be better to just use a larger arbitrary chunk size somewhere in the range of 32-256 entries for the first chunk request?

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.

localfs: File.Readdir is not spec compliant

1 participant