On Mon, May 27, 2024 at 12:16:41AM +0100, Al Viro wrote: > > What would make more sense is if you make the "fd_empty()" test be > > about the _flags_, and then both the fp_empty() test and the test > > inside fdput() would be testing the same things. > > Umm... What encoding would you use? FWIW, _if_ we go for replacement of struct fd with struct-wrapped unsigned long and actually steal another bit from pointer, we could actually use that to encode errors as well... If bit 0 is clear for file reference and set for an error, we could use bit 1 to represent borrowed vs. cloned and bit 2 for need to unlock... overlayfs would be happier that way - we could have those functions return struct fd directly, and pass the error value that way. fdget() would report EBADF explicitly on empty slot - not a big deal. Hmm... Let me play with that a bit and see if I can come up with something tolerable. We could add that in parallel to existing struct fd; we'd need a name for replacement, though - anything like "rawfd" is asking for confusion around fdget_raw(), and we'd need replacements for fdget() et.al. that would yield those. Alternatively, with a sane set of helpers we could actually _replace_ struct fd definition without a huge flagday commit - start with adding #define fd_file(fd) ((fd).file) #define fd_valid(fd) (fd_file(fd) != NULL) convert the current users, one by one (fairly mechanical patches), then change the definition of struct fd. The last step would affect * definitions of helpers * adding fd-constructing macros (ERR_FD, etc.) * converting the few places that really construct those suckers (fdget() et.al., overlayfs, a couple of explicit initializers to {NULL, 0}). It's not a huge amount of work and the flagday step would be fairly small, but we'd probably need to split that over a couple of cycles - helpers in one, along with renaming fd.file to e.g. fd.__file_use_the_damn_helpers, then in the next cycle do the switchover. Hell knows; let me play with that a bit and let's see what falls out...