mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 03:35:32 -04:00
VFS: move delegated_inode retry loop into lookup_open()
By moving this retry into lookup_open() we no longer need to pass around the delegated_inode pointer. Various variable assignments need to be moved out of the declaration block so that they can be repeated after the "goto retry". Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Jori Koolstra <jkoolstra@xs4all.nl> Signed-off-by: NeilBrown <neil@brown.name> Link: https://patch.msgid.link/20260714230534.776886-3-neilb@ownmail.net Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
committed by
Christian Brauner
parent
ddb6e6c72a
commit
a5438415be
43
fs/namei.c
43
fs/namei.c
@@ -4402,17 +4402,23 @@ static struct dentry *atomic_open(const struct path *path, struct dentry *dentry
|
||||
* An error code is returned on failure.
|
||||
*/
|
||||
static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
|
||||
const struct open_flags *op,
|
||||
struct delegated_inode *delegated_inode)
|
||||
const struct open_flags *op)
|
||||
{
|
||||
struct delegated_inode delegated_inode = { };
|
||||
struct mnt_idmap *idmap;
|
||||
struct dentry *dir = nd->path.dentry;
|
||||
struct inode *dir_inode = dir->d_inode;
|
||||
int open_flag = op->open_flag;
|
||||
int open_flag;
|
||||
struct dentry *dentry;
|
||||
int error, create_error = 0;
|
||||
umode_t mode = op->mode;
|
||||
bool got_write = false;
|
||||
int error, create_error;
|
||||
umode_t mode;
|
||||
bool got_write;
|
||||
|
||||
retry:
|
||||
open_flag = op->open_flag;
|
||||
got_write = false;
|
||||
mode = op->mode;
|
||||
create_error = 0;
|
||||
|
||||
if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
|
||||
got_write = !mnt_want_write(nd->path.mnt);
|
||||
@@ -4510,7 +4516,7 @@ 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, LEASE_BREAK_DIR_CREATE, delegated_inode);
|
||||
error = try_break_deleg(dir_inode, LEASE_BREAK_DIR_CREATE, &delegated_inode);
|
||||
if (error)
|
||||
goto out_dput;
|
||||
|
||||
@@ -4545,6 +4551,15 @@ static struct dentry *lookup_open(struct nameidata *nd, struct file *file,
|
||||
if (got_write)
|
||||
mnt_drop_write(nd->path.mnt);
|
||||
|
||||
if (is_delegated(&delegated_inode)) {
|
||||
/* Must have come through out_dput: dentry is an ERR_PTR() */
|
||||
error = break_deleg_wait(&delegated_inode);
|
||||
|
||||
if (!error)
|
||||
goto retry;
|
||||
dentry = ERR_PTR(error);
|
||||
}
|
||||
|
||||
return dentry;
|
||||
|
||||
out_dput:
|
||||
@@ -4592,7 +4607,6 @@ static struct dentry *lookup_fast_for_open(struct nameidata *nd, int open_flag)
|
||||
static const char *open_last_lookups(struct nameidata *nd,
|
||||
struct file *file, const struct open_flags *op)
|
||||
{
|
||||
struct delegated_inode delegated_inode = { };
|
||||
int open_flag = op->open_flag;
|
||||
struct dentry *dentry;
|
||||
const char *res;
|
||||
@@ -4622,19 +4636,10 @@ static const char *open_last_lookups(struct nameidata *nd,
|
||||
return ERR_PTR(-ECHILD);
|
||||
}
|
||||
}
|
||||
retry:
|
||||
dentry = lookup_open(nd, file, op, &delegated_inode);
|
||||
|
||||
if (IS_ERR(dentry)) {
|
||||
if (is_delegated(&delegated_inode)) {
|
||||
int error = break_deleg_wait(&delegated_inode);
|
||||
|
||||
if (!error)
|
||||
goto retry;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
dentry = lookup_open(nd, file, op);
|
||||
if (IS_ERR(dentry))
|
||||
return ERR_CAST(dentry);
|
||||
}
|
||||
|
||||
if (file->f_mode & (FMODE_OPENED | FMODE_CREATED)) {
|
||||
dput(nd->path.dentry);
|
||||
|
||||
Reference in New Issue
Block a user