8000 vfs: Introduce reliable disk enumeration by chrysn · Pull Request #17660 · RIOT-OS/RIOT · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

vfs: Introduce reliable disk enumeration #17660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 17, 2022

Conversation

chrysn
Copy link
Member
@chrysn chrysn commented Feb 15, 2022

Contribution description

Listing mount points was previously documented as racy, and generic modules using it could barely ensure that nothing else in the system would mount/unmount at impractical times (#17658 was an attempt to fix that by making the mutex public, but that had other downsides).

This introduces an iteration mechanism that is thread-safe because it keeps a directory handle open for the currently viewed FS, and that (just like an open file) keeps the FS from being unmounted.

In bycatch and related changes, it

  • removes per-filesystem fstatvfs calls (for lack of reason to have that as a separate driver method, when all users go through the generic statvfs method that has the same properties anyways)
  • alters vfs_iterate_mounts to produce the actual mount sequence (and not some 2-instructions-shorter-but-confusing reordering that is an artifact of clists), thus making it practical to get a view on the mount points that at least captures those mount points that are not altered during iteration
  • introduces dstatvfs (in analogy to fstatvfs, and it's really the slimmest of all the *statvfs calls because the directory readily contains a valid pointer to the FS)
  • fixes details in the docs (gobbling up vfs: Document that open directories are counted #17659)

Testing procedure

A new test covers this:

$ make -C tests/vfs_iterate_mount all test
[...]
Help: Press s to start test, r to print it is ready
READY
s
START
main(): This is RIOT! (Version: 2022.04-devel-379-g882ea6-vfs-drop-per-fs-fstatvfs)
Mounted 1234
N(/const1)N(/const2)N(/const3)N(/const4)O
N(/const1)N(/const2)N(/const4)O
N(/const1)N(/const4)N(/const3)N(/const1)O
All unmounted
O

make: Leaving directory '/home/chrysn/git/RIOT/tests/vfs_iterate_mount'
$

(I tested this with the riot-wrappers, but without actually interspersing mounting with iteration -- and anyhow that's not a practical thing to describe in a PR).

Issues/PRs references

#17658 was an earlier attempt.

The documentation fix was originally in #17659.

[edit: Added reference to #17659; tests described]

The addition is helpful because directories are visibly different from
open files (and generally are not treated like files).
No current file system implements it, there is no defined semantic
difference between running fstatfs and the fallback currently
implemented, and there is practically no optimization gained from not
just running it through a single statvfs.
@github-actions github-actions bot added the Area: sys Area: System label Feb 15, 2022
@chrysn chrysn added Area: fs Area: File systems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation and removed Area: sys Area: System labels Feb 15, 2022
@github-actions github-actions bot added Area: sys Area: System Area: tests Area: tests and testing framework labels Feb 15, 2022
@chrysn chrysn added the CI: run tests If set, CI server will run tests on hardware for the labeled PR label Feb 15, 2022
@chrysn chrysn force-pushed the vfs-drop-per-fs-fstatvfs branch from 882ea6d to bd22de4 Compare February 15, 2022 14:45
@chrysn chrysn requested review from jnohlgard and benpicco February 15, 2022 14:48
@chrysn
Copy link
Member Author
chrysn commented Feb 15, 2022

Tests are now in, were run on native and microbit-v2 (but there isn't anything about this that should be platform dependent).

(And typo fixed, but I don't want to push it and lose my place in the queue :-) )

@chrysn
Copy link
Member Author
chrysn commented Feb 15, 2022

Disabling CI because it worked except for the now fixed Makefile.ci; please reenable when a new result is useful.

@chrysn chrysn removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 15, 2022
/**
* @brief Iterate through all mounted file systems by their root directories
*
* Unlike @ref vfs_iterate_mounts, this is thread safe, and allows thread safe
Copy link
Contributor

Choose a reason for hiding this comment

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

Would probably be a good call to make vfs_iterate_mounts a private function then

Copy link
Member Author

Choose a reason for hiding this comment

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

For release cycle reasons I could only deprecate its public use -- but then it'd probably be prudent to change sc_vfs too, and ...

yeah I've probably just been too lazy to do that. (Nice side effect of that will be that it'll differentiate the previosu error "statvfs failed" into cases of "diropen failed" (thing does not exist) and "statvfs failed" (the FS just doesn't implement statting).)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done now (both the deprecation and the switch in sc_vfs), with a deprecation for public use, becoming internal after 2022.04.

* @ref vfs_DIR).
*
* Users MUST NOT call @ref vfs_closedir if they intend to keep iterating, but
* MUST call it when aborting iteration.
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to require the user to always call ´vfs_closedir()` when they are done, no matter if they abort early or iterated over all mounts?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, it's a trade-off between complexity of the simple thing (just iterating over all, as df does) and loops with breaks (of which I wouldn't know an example, because if you want only one, you'd diropen or statvfs that right away). So I think that this way is the more practical one.

Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO 'you only need to use vfs_closedir() sometimes is inconsistent and will lead to it being forgotten even if needed.

vfs_iterate_mount_dirs() calls vfs_closedir() internally anyway, so why not remove it from there and always have it called by the user, so the behavior is always consistent. "When done iterating, call vfs_closedir()". Not "When done iterating AND no more mount points are left, call vfs_closedir()"

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm just pushing back here because I have a hard time seeing why the loop would be aborted in the first place; can you imagine any situation why it would? Even when paginating mount points one'd need to go through all to get some consistency metric ... although OK, I can envision some patterns of pagination that do work with incomplete lists -- fine, will change it.

(After all it will make the error of someone forgetting to clean up more visible, as they can never unmount after the first iteration).

Copy link
Member Author

Choose a reason for hiding this comment

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

There is one weird corner case that makes me go back on this (noticed when starting work on it): If no file system is mounted at all, that would now require a special case. (You can't just zero out the initial value, then start iterating, function returns false immediately, and then closing the dir goes boom).

Applications would handle that even worse than the current exit condition (and it'd be even rarer in their applications), so I'd stick with the current one.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've been briefly pondering whether it makes sense to, instead of a boolean, return the dir argument. Then it'd behave more like any allocation function, for which "if it returns something, you must free it" (or pass it on, eg. to a realloc) is a more common pattern. Do you think that'd enhance usability? Binary-wise it'd be pretty much the same, provided the conditional branch tests for zeroness (which is the same for ==NULL and ==false).

chrysn added a commit to chrysn-pull-requests/RIOT that referenced this pull request Feb 16, 2022
Use local variable and pass pointer to helper function

See-Also: RIOT-OS#17660 (comment)
@benpicco
Copy link
Contributor

Please squash!

This is a cosmetic change when considering vfs_iterate_mounts alone
(which now reports FSs in precise mount order rather than reporting the
most recently mounted, followed by the rest in mount order), but is
helpful for uses of it that need some guarantees in order to produce
reliable results even when iteration and (un)mounting interact.
... as thread-safe replacement for vfs_iterate_mounts
... adding precision to the documentation where a corner case was
discovered during testing and is permitted.

The test is too large for one small board, just like the other existing
VFS test.
This solves highly theoretical race conditions of file systems being
unmounted in an application while a shell `df` runs, fixes the previous
weird behavior that `/mountpoint/non-existant-path` could be df'd and
would even report that non-existant path as a file name, but more
practically ensures that an example of vfs_iter_mount_dirs is around.
@chrysn chrysn force-pushed the vfs-drop-per-fs-fstatvfs branch from d0da80e to d60f7ae Compare February 16, 2022 18:16
@chrysn chrysn added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 16, 2022
@chrysn chrysn merged commit 40f7c66 into RIOT-OS:master Feb 17, 2022
@chrysn chrysn deleted the vfs-drop-per-fs-fstatvfs branch February 18, 2022 12:53
@OlegHahm OlegHahm added this to the Release 2022.04 milestone Apr 25, 2022
chrysn added a commit to RIOT-OS/rust-riot-sys that referenced this pull request May 31, 2022
Depends-On: RIOT-OS/RIOT#17660

When that is not present, due to an old RIOT version or a riot-sys
version that doesn't yet provide the marker, the mount list is silently
shown as empty.
mguetschow added a commit to mguetschow/RIOT that referenced this pull request Apr 8, 2025
use `vfs_iterate_mount_dirs()` instead

deprecated in RIOT-OS#17660
Lukas-Luger pushed a commit to Lukas-Luger/RIOT that referenced this pull request Apr 14, 2025
use `vfs_iterate_mount_dirs()` instead

deprecated in RIOT-OS#17660
AnnsAnns pushed a commit to AnnsAnns/RIOT that referenced this pull request Apr 16, 2025
use `vfs_iterate_mount_dirs()` instead

deprecated in RIOT-OS#17660
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: fs Area: File systems Area: sys Area: System Area: tests Area: tests and testing framework CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
0