[PATCH 06/12] vfs: lookup_open(): move i_op->create check to before try_break_deleg()

From: Jori Koolstra

Date: Sun Jun 14 2026 - 12:46:27 EST


The i_op->create check in lookup_open() takes place after the
try_break_deleg() call. This does not match the order when doing a
regular file create via mknod(2). There the call order is:

filename_mknodat()
vfs_create()
i_op->create check
try_break_deleg()

Move the i_op->create check to before try_break_deleg() in
lookup_open().

Signed-off-by: Jori Koolstra <jkoolstra@xxxxxxxxx>
---
fs/namei.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index e21f23502e8d..15bf28b85a4e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4341,6 +4341,7 @@ static int may_o_create(struct mnt_idmap *idmap,
const struct path *dir, struct dentry *dentry,
umode_t mode)
{
+
int error = security_path_mknod(dir, dentry, mode, 0);
if (error)
return error;
@@ -4528,16 +4529,17 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,

/* Negative dentry, just create the file */
if (!dentry->d_inode && (open_flag & O_CREAT)) {
- /* but break the directory lease first! */
- error = try_break_deleg(dir_inode, delegated_inode);
- if (error)
- goto out_dput;

if (!dir_inode->i_op->create) {
error = -EACCES;
goto out_dput;
}

+ /* but break the directory lease first! */
+ error = try_break_deleg(dir_inode, delegated_inode);
+ if (error)
+ goto out_dput;
+
error = dir_inode->i_op->create(idmap, dir_inode, dentry,
mode, open_flag & O_EXCL);
if (error)
--
2.54.0