[PATCH 00/10] vfs: add O_CREAT|O_DIRECTORY to open*(2)

From: Jori Koolstra

Date: Sun Jul 12 2026 - 13:55:28 EST


This series implements new semantics for the O_CREAT|O_DIRECTORY flag
combination for open*(2): perform a mkdir and open the resulting
directory; return a pinning fd (which mkdir does not).

Most of the work happens in "vfs: add O_CREAT|O_DIRECTORY to open*(2),"
as may be expected. Before that there is some clean-up work and
preparation. The "vfs: short-circuit MAY_WRITE access for O_DIRECTORY
opens" patch is also worth paying extra attention to as it
short-circuits doomed opening of directories as writable. This check for
regular files is now done very late in do_open(), but for
O_CREAT|O_DIRECTORY this is unacceptable as this would create the
directory and then still fail.

Changes:
v3: https://lore.kernel.org/linux-fsdevel/20260704164149.3480051-1-jkoolstra@xxxxxxxxx/
- address the inconsistency in calling audit_inode_child() in
lookup_open() versus vfs_create() in a separate series.
- fclog.c selftest header fix moved to separate patch.
- add a "with trailing slash test" success test to the included
selftests.
- pass struct qstr by pointer to trailing_slashes() and add a comment
on what it does
- changed commit message of "vfs: add O_CREAT|O_DIRECTORY to
open*(2)" to address comments of Brauner

Jori Koolstra (10):
fs/namei.c: use trailing_slashes()
vfs: prepare vfs_creat|mkdir_no_perm for reuse in lookup_open()
vfs: lookup_open(): move setting FMODE_CREATED down
vfs: move ->create check in lookup_open() to before try_break_deleg()
vfs: lookup_open(): use vfs_create_no_perm()
vfs: add O_CREAT|O_DIRECTORY to open*(2)
vfs: move O_IS_MKDIR check from lookup_open() into individual
filesystems
vfs: refuse O_CREAT for directories through a dangling symlink
vfs: short-circuit MAY_WRITE access for O_DIRECTORY opens
selftest: add tests for open*(O_CREAT|O_DIRECTORY)

fs/9p/vfs_inode.c | 3 +
fs/9p/vfs_inode_dotl.c | 3 +
fs/ceph/file.c | 3 +
fs/fuse/dir.c | 3 +
fs/gfs2/inode.c | 3 +
fs/namei.c | 224 ++++++++++++------
fs/nfs/dir.c | 6 +
fs/open.c | 32 ++-
fs/smb/client/dir.c | 3 +
fs/vboxsf/dir.c | 3 +
include/linux/fcntl.h | 6 +
.../testing/selftests/filesystems/.gitignore | 1 +
tools/testing/selftests/filesystems/Makefile | 2 +-
.../filesystems/open_o_creat_o_dir.c | 201 ++++++++++++++++
.../testing/selftests/filesystems/wrappers.h | 11 +
15 files changed, 419 insertions(+), 85 deletions(-)
create mode 100644 tools/testing/selftests/filesystems/open_o_creat_o_dir.c

--
2.55.0