Re: [PATCH v3 09/14] vfs: add O_CREAT|O_DIRECTORY to open*(2)

From: NeilBrown

Date: Mon Jul 13 2026 - 17:39:00 EST


On Mon, 13 Jul 2026, Christoph Hellwig wrote:
> On Tue, Jul 07, 2026 at 12:04:18PM +0200, Christian Brauner wrote:
> > I don't think any of this is really an argument worth considering.
>
> It very much is.
>
> > This is a lot of handwaving for the sake of portability and concerns
> > about past API mistakes. To both: so what. If an API is useful it's
> > useful, POSIX be damned. We're not going to be fenced in by some
> > standard.
> >
> > 90% of our interfaces blow way past POSIX already - in most subsystems.
> > If we'd back down ever time someone shows up with "what about POSIX"
> > Linux would be irrelevant.
>
> You can totaally ignore posix. We need an interface that is self
> discoverable on Linux. Any combination of flags that was accepted
> by previous kernels and gave different results than the new interface
> do not qualify for that.
>
> > It's been years since O_DIRECTORY | O_CREAT has been made consistent
> > which means all LTS kernels have consistent behavior. We often make flag
> > combinations work that didn't work or where inconsisent before. Nothing
> > here is special at all.
>
> No, we can't rely on something being backport to old enterprise/cloud
> kernel. Doing so makes the interface unusable for actual applications.
>
> >
> > I appreciate the concern but even if this were to fall flat then
> > worst-case we'd add a new flag and we'd still make that work. But I see
> > no reason to not try the semantically obvious thing and make
> > O_DIRECTORY | O_CREAT work.
>
> New flag as in new O_ flag for open does not work because open never
> checked flag. Which has always been a giant PITA, but as long as we're
> dealing with legacy open(2) that is what it is.
>
>

So let's add OPENAT2_NEW_COMBINATION which instructs openat2() to reject
unrecognised combinations. Old kernels will simply reject that.
New kernels can start using previously unsupported combinations safely.
Initially reject
- O_DIRECTORY with any O_CREAT O_NOCTTY O_TRUNC O_APPEND O_*SYNC
O_DIRECT
- O_EXCL without O_CREAT
- O_NOCTTY with O_CREAT O_TRUNC O_APPEND ...
- O_APPEND without O_WRONLY/O_RDWR

and probably others. O_TMPFILE woth O_EXCL, O_CREAT with O_EMPTYPATH ....

Then the O_DIRECTORY|O_CREAT patch set changes that to allow O_DIRECTORY
with O_CREATE and user-space code that wants to probe attempts to openat2()
with

OPENAT2_NEW_COMBINATION|O_DIRECTORY|O_CREATE|O_RDONLY

Maybe OPENAT2_NEW_COMBINATION could just reject *everything* at first,
then incrementally allow new combinations as they are defined. Old
combinations can always be accessed without OPENAT2_NEW_COMBINATION.

NeilBrown