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

Jori Koolstra posted 12 patches 1 week, 4 days ago
fs/9p/vfs_inode.c                             |   5 +
fs/9p/vfs_inode_dotl.c                        |   5 +
fs/ceph/file.c                                |   5 +
fs/fuse/dir.c                                 |   5 +
fs/gfs2/inode.c                               |   5 +
fs/namei.c                                    | 247 ++++++++++-----
fs/nfs/dir.c                                  |  10 +
fs/open.c                                     |  32 +-
fs/smb/client/dir.c                           |   5 +
fs/vboxsf/dir.c                               |   5 +
include/linux/fcntl.h                         |   6 +
include/uapi/asm-generic/errno.h              |   2 +-
.../testing/selftests/filesystems/.gitignore  |   1 +
tools/testing/selftests/filesystems/Makefile  |   2 +-
.../filesystems/open_o_creat_o_dir.c          | 296 ++++++++++++++++++
.../testing/selftests/filesystems/wrappers.h  |  11 +
16 files changed, 554 insertions(+), 88 deletions(-)
create mode 100644 tools/testing/selftests/filesystems/open_o_creat_o_dir.c
[PATCH v6 00/12] vfs: add O_CREAT|O_DIRECTORY to open*(2)
Posted by Jori Koolstra 1 week, 4 days ago
Hi Christian/Neil,

Finally got back from holiday. I know Neil is also attempting to make
changes to the same code paths as the O_CREAT|O_DIRECTORY series touch,
so I hope, now that I have a bit more time, that I can push this
forwards before I have to do more rebasing.

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 (to
prevent one from opening directories as writable) is currently done very
late in do_open(), after an inode has been obtained. However, when
introducing O_CREAT|O_DIRECTORY this is unacceptable as it would create
the directory and then still fail. This patch does however change some
user visible error codes.

Moreover, "vfs: change ->create/->mkdir operations unavailable errno"
also changes the ->create and ->mkdir unavailable errnos to -EOPNOTSUPP.
A previous attempt to do this more widely stranded before.[1] However,
that regression was only for vfat and does seem specific to changing the
return code from vfs_symlink(). We can drop this patch if needed, but it
would be _really_ ugly.

Changes from vn to v(n+1):
v5: https://lore.kernel.org/linux-fsdevel/20260823160706.358293-1-jkoolstra@xs4all.nl/
   - Uniformize ->create and ->mkdir unavailable errnos to -EOPNOTSUPP.
   - Return -EOPNOTSUPP instead of -ENOENT when O_CREAT|O_DIRECTORY is
     not supported by a ->atomic_open filesystem.
   - Added test cases for dangling symlink and sticky directory
     behaviour, and a test that verifies O_TMPFILE|O_CREAT is still
     -EINVAL.
   - Split off "vfs: lookup_open(): lock the parent as I_MUTEX_PARENT"
     as a separate patch.
   - Fixed the issues pointed out by Brauner in v5.
v4: https://lore.kernel.org/linux-fsdevel/20260712175539.1565444-1-jkoolstra@xs4all.nl/
   - rebased on 7.2, which includes my changes to auditing in
     lookup_open() as well as Neil Brown's changes to the same function
     for the implementation of vfs_lookup_open().
v3: https://lore.kernel.org/linux-fsdevel/20260704164149.3480051-1-jkoolstra@xs4all.nl/
   - 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

[1]: https://lore.kernel.org/linux-fsdevel/90228c39-04e7-41ef-ad91-84a8bb866650@sirena.org.uk/

Jori Koolstra (12):
  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: lookup_open(): lock the parent as I_MUTEX_PARENT
  vfs: add O_CREAT|O_DIRECTORY to open*(2)
  vfs: change ->create/->mkdir operations unavailable errno
  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                             |   5 +
 fs/9p/vfs_inode_dotl.c                        |   5 +
 fs/ceph/file.c                                |   5 +
 fs/fuse/dir.c                                 |   5 +
 fs/gfs2/inode.c                               |   5 +
 fs/namei.c                                    | 247 ++++++++++-----
 fs/nfs/dir.c                                  |  10 +
 fs/open.c                                     |  32 +-
 fs/smb/client/dir.c                           |   5 +
 fs/vboxsf/dir.c                               |   5 +
 include/linux/fcntl.h                         |   6 +
 include/uapi/asm-generic/errno.h              |   2 +-
 .../testing/selftests/filesystems/.gitignore  |   1 +
 tools/testing/selftests/filesystems/Makefile  |   2 +-
 .../filesystems/open_o_creat_o_dir.c          | 296 ++++++++++++++++++
 .../testing/selftests/filesystems/wrappers.h  |  11 +
 16 files changed, 554 insertions(+), 88 deletions(-)
 create mode 100644 tools/testing/selftests/filesystems/open_o_creat_o_dir.c


base-commit: 2f0c1cf72f4682178506f513bbf015e591b1aa4a
-- 
2.55.0
Re: [PATCH v6 00/12] vfs: add O_CREAT|O_DIRECTORY to open*(2)
Posted by Christian Brauner 1 week ago
On Sun, 13 Sep 2026 20:50:04 +0200, Jori Koolstra wrote:
> Finally got back from holiday. I know Neil is also attempting to make
> changes to the same code paths as the O_CREAT|O_DIRECTORY series touch,
> so I hope, now that I have a bit more time, that I can push this
> forwards before I have to do more rebasing.
> 
> 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).
> 
> [...]

Applied to the vfs-7.4.lookup branch of the vfs/vfs.git tree.
Patches in the vfs-7.4.lookup branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.4.lookup

[01/12] fs/namei.c: use trailing_slashes()
        https://git.kernel.org/vfs/vfs/c/614d27b66efd
[02/12] vfs: prepare vfs_creat|mkdir_no_perm for reuse in lookup_open()
        https://git.kernel.org/vfs/vfs/c/2eacbb993f65
[03/12] vfs: lookup_open(): move setting FMODE_CREATED down
        https://git.kernel.org/vfs/vfs/c/db4a1ea6a55e
[04/12] vfs: move ->create check in lookup_open() to before try_break_deleg()
        https://git.kernel.org/vfs/vfs/c/27ab83a2c268
[05/12] vfs: lookup_open(): use vfs_create_no_perm()
        https://git.kernel.org/vfs/vfs/c/900d6abddd54
[06/12] vfs: lookup_open(): lock the parent as I_MUTEX_PARENT
        https://git.kernel.org/vfs/vfs/c/0567a62f5ea1
[07/12] vfs: add O_CREAT|O_DIRECTORY to open*(2)
        https://git.kernel.org/vfs/vfs/c/596e3a392d61
[08/12] vfs: change ->create/->mkdir operations unavailable errno
        https://git.kernel.org/vfs/vfs/c/dc6315c50724
[09/12] vfs: move O_IS_MKDIR check from lookup_open() into individual filesystems
        https://git.kernel.org/vfs/vfs/c/885bf5afa273
[10/12] vfs: refuse O_CREAT for directories through a dangling symlink
        https://git.kernel.org/vfs/vfs/c/c7a93442a9b2
[11/12] vfs: short-circuit MAY_WRITE access for O_DIRECTORY opens
        https://git.kernel.org/vfs/vfs/c/093f13c7a954
[12/12] selftest: add tests for open*(O_CREAT|O_DIRECTORY)
        https://git.kernel.org/vfs/vfs/c/76208ee704c2
Re: [PATCH v6 00/12] vfs: add O_CREAT|O_DIRECTORY to open*(2)
Posted by Christian Brauner 1 week ago
On Thu, Sep 17, 2026 at 12:38:33PM +0200, Christian Brauner wrote:
> On Sun, 13 Sep 2026 20:50:04 +0200, Jori Koolstra wrote:
> > Finally got back from holiday. I know Neil is also attempting to make
> > changes to the same code paths as the O_CREAT|O_DIRECTORY series touch,
> > so I hope, now that I have a bit more time, that I can push this
> > forwards before I have to do more rebasing.
> > 
> > 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).
> > 
> > [...]
> 
> Applied to the vfs-7.4.lookup branch of the vfs/vfs.git tree.
> Patches in the vfs-7.4.lookup branch should appear in linux-next soon.

Dropped after I reviewed it once more. But we're close, I think.