mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
18
fs/nfs/dir.c
18
fs/nfs/dir.c
@@ -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);
|
||||
|
||||
10
fs/open.c
10
fs/open.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user