On Tue, Mar 10, 2020 at 12:25 AM David Howells <dhowells@xxxxxxxxxx> wrote: ? > Okay. So what's the equivalent of AT_SYMLINK_NOFOLLOW in RESOLVE_* flag > terms? Nothing. openat2() takes two sets of flags. We'll never get rid of AT_SYMLINK_NOFOLLOW / O_NOFOLLOW, and we've added RESOLVE_NO_SYMLINKS to the new set of flags. It's just a separate namespace. We will _not_ be adding a RESOLVE_XYZ flag for O_NOFOLLOW or AT_SYMLINK_NOFOLLOW. At least not visible to user space - because as people already figured out, that just causes problems with consistency issues. And yes, the fact that we then have three different user-visible namespaces (O_xyz flags for open(), AT_xyz flags for linkat(), and now RESOLVE_xyz flags for openat2()) is sad and messy. But it's an inherent messiness from just how the world works. We can't get rid of it. If we need linkat2() and friends, so be it. Do we? Could we have a _fourth_ set of flags that are simply for internal use that is a superset of them all? Sure. But no, it's almost certainly not worth it. Four is not better than three. Now, some type-safety in the kernel to make sure that we can't mix AT_xyz with O_xyz or RESOLVE_xyz - that might be worth it. Although judging by past experience, not enough people run sparse for it to really be worth it. Linus PS. Yeah, we also have that LOOKUP_xyz namespace, and the access mode namespace, so we already have those internal format versions too.