Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9850c056 authored by Al Viro's avatar Al Viro
Browse files

Fix the -ESTALE handling in do_filp_open()



Instead of playing sick games with path saving, cleanups, just retry
the entire thing once with LOOKUP_REVAL added.  Post-.34 we'll convert
all -ESTALE handling in there to that style, rather than playing with
many retry loops deep in the call chain.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 806892e9
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -1604,11 +1604,12 @@ struct file *do_filp_open(int dfd, const char *pathname,
	struct file *filp;
	struct nameidata nd;
	int error;
	struct path path, save;
	struct path path;
	struct dentry *dir;
	int count = 0;
	int will_truncate;
	int flag = open_to_namei_flags(open_flag);
	int force_reval = 0;

	/*
	 * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
@@ -1660,9 +1661,12 @@ struct file *do_filp_open(int dfd, const char *pathname,
	/*
	 * Create - we need to know the parent.
	 */
reval:
	error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
	if (error)
		return ERR_PTR(error);
	if (force_reval)
		nd.flags |= LOOKUP_REVAL;
	error = path_walk(pathname, &nd);
	if (error) {
		if (nd.root.mnt)
@@ -1854,17 +1858,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
	error = security_inode_follow_link(path.dentry, &nd);
	if (error)
		goto exit_dput;
	save = nd.path;
	path_get(&save);
	error = __do_follow_link(&path, &nd);
	if (error == -ESTALE) {
		/* nd.path had been dropped */
		nd.path = save;
		path_get(&nd.path);
		nd.flags |= LOOKUP_REVAL;
	error = __do_follow_link(&path, &nd);
	}
	path_put(&save);
	path_put(&path);
	if (error) {
		/* Does someone understand code flow here? Or it is only
@@ -1874,6 +1868,10 @@ struct file *do_filp_open(int dfd, const char *pathname,
		release_open_intent(&nd);
		if (nd.root.mnt)
			path_put(&nd.root);
		if (error == -ESTALE && !force_reval) {
			force_reval = 1;
			goto reval;
		}
		return ERR_PTR(error);
	}
	nd.flags &= ~LOOKUP_PARENT;