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(). Reviewed-by: NeilBrown Signed-off-by: Jori Koolstra --- fs/namei.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index a43e64717d11..aaba03954cd5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4520,16 +4520,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)) { + if (!dir_inode->i_op->create) { + error = -EACCES; + goto out_dput; + } + /* but break the directory lease first! */ error = try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, delegated_inode); if (error) goto out_dput; audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); - if (!dir_inode->i_op->create) { - error = -EACCES; - goto out_dput; - } error = dir_inode->i_op->create(idmap, dir_inode, dentry, mode, open_flag & O_EXCL); -- 2.55.0