<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Nov 8, 2024 at 6:02 AM Rob Landley <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 11/7/24 11:47, enh wrote:<br>
> looking at<br>
> <a href="https://lore.kernel.org/lkml/20241107005831.15434-1-elsk@google.com/T/#u" rel="noreferrer" target="_blank">https://lore.kernel.org/lkml/20241107005831.15434-1-elsk@google.com/T/#u</a> i<br>
> note that there _is_ a difference between glibc readdir() and bionic/musl<br>
> readdir() --- glibc explicitly doesn't report any entry where d_ino is 0.<br>
<br>
Is 0 a valid inode number in some filesystem?<br>
<br>
They were talking about find, and toybox find does DIRTREE_STATLESS and <br>
then does its own stat discarding ENOENT (line 224 of find.c) to avoid <br>
the race hole, but possibly dirtree itself should be handling that <br>
internally?<br>
<br>
> i couldn't find any documentation on this, so i don't know whether this is<br>
> some undocumented thing that linux expects libc to do or what.<br>
<br>
If glibc is doing it, 80% chance it's <br>
<a href="https://www.psychologytoday.com/us/blog/thinking-makes-it-so/201402/the-pot-roast-principle" rel="noreferrer" target="_blank">https://www.psychologytoday.com/us/blog/thinking-makes-it-so/201402/the-pot-roast-principle</a> <br>
at best, but let's see... Nope, looks like it got reverted in 2022:<br>
<br>
<a href="https://sourceware.org/git/?p=glibc.git;a=commit;h=766b73768b29" rel="noreferrer" target="_blank">https://sourceware.org/git/?p=glibc.git;a=commit;h=766b73768b29</a><br>
<br>
Because 0 is a valid inode in xfs. Go figure.<br></blockquote><div><br></div><div>ah, thanks. i did think it was weird that i couldn't find "0 is special" anywhere, so suspected _some_ fs would be using it. (though tbh i guessed something like procfs rather than a "real" fs.)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> but i<br>
> thought you might be interested, since two of your five libcs aren't doing<br>
> it, and you may or may not want to do it in your wrapper?<br>
<br>
Right now find.c is manually compensating for stat failure due to <br>
deletion while traversing, because it came up. And ls.c is also doing <br>
it, and there's a use in sh.c in pending. Meanwhile ps is instead using <br>
DIRTREE_SHUTUP.<br>
<br>
> (i'm _assuming_<br>
> the bsd/macOS kernels just do this themselves rather than leaving it as<br>
> userspace's problem, since they tend to lean that way. though i'm not<br>
> really sure what exact state "returned from getdents64(2) but with d_ino 0"<br>
> actually _means_, so it's possible there's a legit use to reporting this to<br>
> userspace?)<br>
<br>
I don't entirely understand what the objection is, but I haven't exactly <br>
had the calmest week of regular sleep schedule...<br>
<br>
If you're suggesting that dirtree should handle both the SHUTUP and <br>
STATLESS cases internally/automatically... quite possibly? The question <br>
would be why it isn't already.<br></blockquote><div><br></div><div>no, really i was asking "have you heard of this?".</div><div><br></div><div>certainly my knee-jerk reaction to the bug was "duh, don't modify the directory you're traversing!" but allegedly they can't reproduce with glibc/gnu find, which seemed weird.</div><div> </div><div>i'm happy to keep calling this user error, though, and your example certainly convinces me not to touch libc!</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
In the case of STATLESS I think it was because "readdir can see it but <br>
stat can't access it" is some permission flag combination we have to <br>
deal with and probably have a test for in the testsuite. (A directory <br>
that's +r but -x or vice versa.) Both commands need to find and display <br>
things it can't tell you anything _about_ other than that it exists (and <br>
the type info returned by readdir itself about whether it's a directory <br>
or symlink or whatnot).<br>
<br>
In the case of SHUTUP, that tells dirtree_add_node() not to report any <br>
errno to stderr. It's already doing a fallback where it tries a second <br>
stat with AT_SYMLINK_NOFOLLOW if it got ENOENT the first time, and in <br>
fact STATLESS doesn't tell it not to TRY to stat, it just says return <br>
the node with memset(0) stat even if you couldn't stat it (with the type <br>
info from readdir patched in to the appropriate field). If you JUST give <br>
it SHUTUP then it discards the node when it couldn't stat it (returning <br>
NULL) and dirtree_recurse() iterates right past that (the continue; on <br>
lib/dirtree.c line 184).<br>
<br>
So it looks to me like the currently behavior's probably right-ish?<br>
<br>
Rob<br>
</blockquote></div></div>