Date: Thu, 13 Jan 2022 06:52:01 +0000 (UTC) From: RVP <r...@sdf.org> Message-ID: <91af8c4-d0bd-c31d-6b6a-355826d5...@sdf.org>
| The EINVAL is caused by using readlink() on what was a symlink, | but, is not anymore because the fd now points to a regular file. The analysis looks right, but | Anyway, here's one more patch: | | ---START PATCH--- | --- sys/miscfs/procfs/procfs_vnops.c.orig 2022-01-12 20:57:25.944841288 +0000 | +++ sys/miscfs/procfs/procfs_vnops.c 2022-01-12 23:07:44.736070587 +0000 that cannot be more than papering over one special case. This problem isn't in procfs, but in ls, and is hard to fix. The general issus is that any directory can change while ls is processing it, leading to either incorrect (or even nonsense) output, or apparent errors. procfs is only notable here by being more dynamic than most filesystems, and its self/fd subr particularly in that it changes as the process opens and closes files - if ls was being run with -RL it might recurse forever (I did not test it though). Any fix for this would need to be in ls, not procfs. If we were willing to permit the extra overhead, and the possibility that it might never terminate, then we coukd have is stat every file again just as it is preparing the output, and in case an inconsistency is discovered, go back and start again (which would mean needing to buffer all output until all was known to be consistent, as the sort results might differ with updated info about the file). But that's too much to expect, and in any case would require the following more reasonable change to have any hope of the preceding terminating. That is for ls itself to make sure to do nothing which can create or remove any files while it is collecting its info, so that we can avoid the almost guaranteed problem observed here - so no opening or closing any files either which provides a challenge for implementing recursive listings, but that could be mitigated by requiring stabikity onky while reading any one directory, alowing sub-dirs to be opened only after completing collecting info from the current dir. This doesn't prevent inconsistencies, but it should prevent ls from itself causing the issue, guaranteeing bad output (for dirs like /proc/x/fd). Or we could do a subset of that, and just not close the dir, even when ls has reached EOF until all entries have had their data collected, so ls would at leas be doing its stat() on the same files it read. This should be easy to implement, but is really just a fix for this one obscure issue (no-one normally has any interest in getting a listing of ls's fd subdir of /proc!) Or we could simply accept that thus cannot be perfect, static listings of dynamic data will have issues - potential issues at a minimum, and attempting to fix that completely is either impossible, or at least so costly as to be n9t worth it (we could add an O_FREEZE open option to essentially make a snapshot of the file/directory while tge returned fd is open, guaranteeing that all references via that fd would see unchanged data). But singling out procfs for special attention isn't the right thing to do (/tmp can have similar problems, slightly less reproducible, when used with shells that implement pipes or command substitution (or similar, like bash's process substitution) using files (or fifos) in /tmp). kre