diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-03 10:59:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-03 10:59:31 -0700 |
commit | 829745b75a1af25bfb0c7dc36640548c98c57169 (patch) | |
tree | 3c7b93e2ff5c3367dc8056cb69adb17c041f39ef | |
parent | 867e4513fe4ba7e7a7ff6a59a1fbbc7d54f443c7 (diff) | |
parent | 2944ebee9a96c9d2ddb9c9cb99df6105f2de62ff (diff) |
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...))
-rw-r--r-- | fs/9p/vfs_inode.c | 34 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 15 | ||||
-rw-r--r-- | fs/fuse/dir.c | 21 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 26 | ||||
-rw-r--r-- | fs/nfs/dir.c | 18 | ||||
-rw-r--r-- | fs/open.c | 10 | ||||
-rw-r--r-- | fs/smb/client/dir.c | 8 | ||||
-rw-r--r-- | fs/vboxsf/dir.c | 25 |
8 files changed, 54 insertions, 103 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 399d455d50d6..d0c77ec31b1d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -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; } /** diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 5b5fda617b80..be297e335468 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -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; } diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 5c569c3cb53f..ecaec0fea3a1 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -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); } /* diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 8760e7e20c9d..8a7ed80d9f2d 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -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; diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d81217923936..5f7d9be6f022 100644 --- a/fs/nfs/dir.c +++ b/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); diff --git a/fs/open.c b/fs/open.c index 9655158c3885..4890b13461c7 100644 --- a/fs/open.c +++ b/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; } diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 5223edf6d11a..47710aa13822 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -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(); diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c index 770e29ec3557..42bedc4ec7af 100644 --- a/fs/vboxsf/dir.c +++ b/fs/vboxsf/dir.c @@ -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) |