Merge tag 'pull-finish_no_open' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull finish_no_open updates from Al Viro:
 "finish_no_open calling conventions change to simplify callers"

* tag 'pull-finish_no_open' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  slightly simplify nfs_atomic_open()
  simplify gfs2_atomic_open()
  simplify fuse_atomic_open()
  simplify nfs_atomic_open_v23()
  simplify vboxsf_dir_atomic_open()
  simplify cifs_atomic_open()
  9p: simplify v9fs_vfs_atomic_open_dotl()
  9p: simplify v9fs_vfs_atomic_open()
  allow finish_no_open(file, ERR_PTR(-E...))
This commit is contained in:
Linus Torvalds
2025-10-03 10:59:31 -07:00
8 changed files with 54 additions and 103 deletions

View File

@@ -768,22 +768,18 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
struct v9fs_inode __maybe_unused *v9inode;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct dentry *res = NULL;
struct inode *inode;
int p9_omode;
if (d_in_lookup(dentry)) {
res = v9fs_vfs_lookup(dir, dentry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
if (res)
dentry = res;
struct dentry *res = v9fs_vfs_lookup(dir, dentry, 0);
if (res || d_really_is_positive(dentry))
return finish_no_open(file, res);
}
/* Only creates */
if (!(flags & O_CREAT) || d_really_is_positive(dentry))
return finish_no_open(file, res);
if (!(flags & O_CREAT))
return finish_no_open(file, NULL);
v9ses = v9fs_inode2v9ses(dir);
perm = unixmode2p9mode(v9ses, mode);
@@ -795,17 +791,17 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
"write-only file with writeback enabled, creating w/ O_RDWR\n");
}
fid = v9fs_create(v9ses, dir, dentry, NULL, perm, p9_omode);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
goto error;
}
if (IS_ERR(fid))
return PTR_ERR(fid);
v9fs_invalidate_inode_attr(dir);
inode = d_inode(dentry);
v9inode = V9FS_I(inode);
err = finish_open(file, dentry, generic_file_open);
if (err)
goto error;
if (unlikely(err)) {
p9_fid_put(fid);
return err;
}
file->private_data = fid;
#ifdef CONFIG_9P_FSCACHE
@@ -818,13 +814,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
v9fs_open_fid_add(inode, &fid);
file->f_mode |= FMODE_CREATED;
out:
dput(res);
return err;
error:
p9_fid_put(fid);
goto out;
return 0;
}
/**

View File

@@ -238,20 +238,16 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
struct p9_fid *dfid = NULL, *ofid = NULL;
struct v9fs_session_info *v9ses;
struct posix_acl *pacl = NULL, *dacl = NULL;
struct dentry *res = NULL;
if (d_in_lookup(dentry)) {
res = v9fs_vfs_lookup(dir, dentry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
if (res)
dentry = res;
struct dentry *res = v9fs_vfs_lookup(dir, dentry, 0);
if (res || d_really_is_positive(dentry))
return finish_no_open(file, res);
}
/* Only creates */
if (!(flags & O_CREAT) || d_really_is_positive(dentry))
return finish_no_open(file, res);
if (!(flags & O_CREAT))
return finish_no_open(file, NULL);
v9ses = v9fs_inode2v9ses(dir);
@@ -337,7 +333,6 @@ out:
p9_fid_put(ofid);
p9_fid_put(fid);
v9fs_put_acl(dacl, pacl);
dput(res);
return err;
}

View File

@@ -739,22 +739,18 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
int err;
struct mnt_idmap *idmap = file_mnt_idmap(file);
struct fuse_conn *fc = get_fuse_conn(dir);
struct dentry *res = NULL;
if (fuse_is_bad(dir))
return -EIO;
if (d_in_lookup(entry)) {
res = fuse_lookup(dir, entry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
if (res)
entry = res;
struct dentry *res = fuse_lookup(dir, entry, 0);
if (res || d_really_is_positive(entry))
return finish_no_open(file, res);
}
if (!(flags & O_CREAT) || d_really_is_positive(entry))
goto no_open;
if (!(flags & O_CREAT))
return finish_no_open(file, NULL);
/* Only creates */
file->f_mode |= FMODE_CREATED;
@@ -768,16 +764,13 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
goto mknod;
} else if (err == -EEXIST)
fuse_invalidate_entry(entry);
out_dput:
dput(res);
return err;
mknod:
err = fuse_mknod(idmap, dir, entry, mode, 0);
if (err)
goto out_dput;
no_open:
return finish_no_open(file, res);
return err;
return finish_no_open(file, NULL);
}
/*

View File

@@ -1368,27 +1368,19 @@ static int gfs2_atomic_open(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned flags,
umode_t mode)
{
struct dentry *d;
bool excl = !!(flags & O_EXCL);
if (!d_in_lookup(dentry))
goto skip_lookup;
d = __gfs2_lookup(dir, dentry, file);
if (IS_ERR(d))
return PTR_ERR(d);
if (d != NULL)
dentry = d;
if (d_really_is_positive(dentry)) {
if (!(file->f_mode & FMODE_OPENED))
if (d_in_lookup(dentry)) {
struct dentry *d = __gfs2_lookup(dir, dentry, file);
if (file->f_mode & FMODE_OPENED) {
if (IS_ERR(d))
return PTR_ERR(d);
dput(d);
return excl && (flags & O_CREAT) ? -EEXIST : 0;
}
if (d || d_really_is_positive(dentry))
return finish_no_open(file, d);
dput(d);
return excl && (flags & O_CREAT) ? -EEXIST : 0;
}
BUG_ON(d != NULL);
skip_lookup:
if (!(flags & O_CREAT))
return -ENOENT;

View File

@@ -2198,8 +2198,6 @@ no_open:
else
dput(dentry);
}
if (IS_ERR(res))
return PTR_ERR(res);
return finish_no_open(file, res);
}
EXPORT_SYMBOL_GPL(nfs_atomic_open);
@@ -2260,7 +2258,7 @@ int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned int open_flags,
umode_t mode)
{
struct dentry *res = NULL;
/* Same as look+open from lookup_open(), but with different O_TRUNC
* handling.
*/
@@ -2275,21 +2273,15 @@ int nfs_atomic_open_v23(struct inode *dir, struct dentry *dentry,
if (error)
return error;
return finish_open(file, dentry, NULL);
} else if (d_in_lookup(dentry)) {
}
if (d_in_lookup(dentry)) {
/* The only flags nfs_lookup considers are
* LOOKUP_EXCL and LOOKUP_RENAME_TARGET, and
* we want those to be zero so the lookup isn't skipped.
*/
struct dentry *res = nfs_lookup(dir, dentry, 0);
d_lookup_done(dentry);
if (unlikely(res)) {
if (IS_ERR(res))
return PTR_ERR(res);
return finish_no_open(file, res);
}
res = nfs_lookup(dir, dentry, 0);
}
return finish_no_open(file, NULL);
return finish_no_open(file, res);
}
EXPORT_SYMBOL_GPL(nfs_atomic_open_v23);

View File

@@ -1059,18 +1059,20 @@ EXPORT_SYMBOL(finish_open);
* finish_no_open - finish ->atomic_open() without opening the file
*
* @file: file pointer
* @dentry: dentry or NULL (as returned from ->lookup())
* @dentry: dentry, ERR_PTR(-E...) or NULL (as returned from ->lookup())
*
* This can be used to set the result of a successful lookup in ->atomic_open().
* This can be used to set the result of a lookup in ->atomic_open().
*
* NB: unlike finish_open() this function does consume the dentry reference and
* the caller need not dput() it.
*
* Returns "0" which must be the return value of ->atomic_open() after having
* called this function.
* Returns 0 or -E..., which must be the return value of ->atomic_open() after
* having called this function.
*/
int finish_no_open(struct file *file, struct dentry *dentry)
{
if (IS_ERR(dentry))
return PTR_ERR(dentry);
file->f_path.dentry = dentry;
return 0;
}

View File

@@ -484,8 +484,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
* in network traffic in the other paths.
*/
if (!(oflags & O_CREAT)) {
struct dentry *res;
/*
* Check for hashed negative dentry. We have already revalidated
* the dentry and it is fine. No need to perform another lookup.
@@ -493,11 +491,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
if (!d_in_lookup(direntry))
return -ENOENT;
res = cifs_lookup(inode, direntry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
return finish_no_open(file, res);
return finish_no_open(file, cifs_lookup(inode, direntry, 0));
}
xid = get_xid();

View File

@@ -315,46 +315,39 @@ static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
{
struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
struct vboxsf_handle *sf_handle;
struct dentry *res = NULL;
u64 handle;
int err;
if (d_in_lookup(dentry)) {
res = vboxsf_dir_lookup(parent, dentry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
if (res)
dentry = res;
struct dentry *res = vboxsf_dir_lookup(parent, dentry, 0);
if (res || d_really_is_positive(dentry))
return finish_no_open(file, res);
}
/* Only creates */
if (!(flags & O_CREAT) || d_really_is_positive(dentry))
return finish_no_open(file, res);
if (!(flags & O_CREAT))
return finish_no_open(file, NULL);
err = vboxsf_dir_create(parent, dentry, mode, false, flags & O_EXCL, &handle);
if (err)
goto out;
return err;
sf_handle = vboxsf_create_sf_handle(d_inode(dentry), handle, SHFL_CF_ACCESS_READWRITE);
if (IS_ERR(sf_handle)) {
vboxsf_close(sbi->root, handle);
err = PTR_ERR(sf_handle);
goto out;
return PTR_ERR(sf_handle);
}
err = finish_open(file, dentry, generic_file_open);
if (err) {
/* This also closes the handle passed to vboxsf_create_sf_handle() */
vboxsf_release_sf_handle(d_inode(dentry), sf_handle);
goto out;
return err;
}
file->private_data = sf_handle;
file->f_mode |= FMODE_CREATED;
out:
dput(res);
return err;
return 0;
}
static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry)