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

Commit 6de88d72 authored by Al Viro's avatar Al Viro
Browse files

kill __link_path_walk()/link_path_walk() distinction



put retry logics into path_walk() and do_filp_open()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 258fa999
Loading
Loading
Loading
Loading
+34 −34
Original line number Diff line number Diff line
@@ -108,8 +108,6 @@
 * any extra contention...
 */

static int __link_path_walk(const char *name, struct nameidata *nd);

/* In order to reduce some races, while at the same time doing additional
 * checking and hopefully speeding things up, we copy filenames to the
 * kernel data space before using them..
@@ -529,35 +527,6 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
	return result;
}

/*
 * Wrapper to retry pathname resolution whenever the underlying
 * file system returns an ESTALE.
 *
 * Retry the whole path once, forcing real lookup requests
 * instead of relying on the dcache.
 */
static __always_inline int link_path_walk(const char *name, struct nameidata *nd)
{
	struct path save = nd->path;
	int result;

	/* make sure the stuff we saved doesn't go away */
	path_get(&save);

	result = __link_path_walk(name, nd);
	if (result == -ESTALE) {
		/* nd->path had been dropped */
		nd->path = save;
		path_get(&nd->path);
		nd->flags |= LOOKUP_REVAL;
		result = __link_path_walk(name, nd);
	}

	path_put(&save);

	return result;
}

static __always_inline void set_root(struct nameidata *nd)
{
	if (!nd->root.mnt) {
@@ -569,6 +538,8 @@ static __always_inline void set_root(struct nameidata *nd)
	}
}

static int link_path_walk(const char *, struct nameidata *);

static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
{
	int res = 0;
@@ -834,7 +805,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
 * Returns 0 and nd will have valid dentry and mnt on success.
 * Returns error and drops reference to input namei data on failure.
 */
static int __link_path_walk(const char *name, struct nameidata *nd)
static int link_path_walk(const char *name, struct nameidata *nd)
{
	struct path next;
	struct inode *inode;
@@ -1016,8 +987,27 @@ static int __link_path_walk(const char *name, struct nameidata *nd)

static int path_walk(const char *name, struct nameidata *nd)
{
	struct path save = nd->path;
	int result;

	current->total_link_count = 0;

	/* make sure the stuff we saved doesn't go away */
	path_get(&save);

	result = link_path_walk(name, nd);
	if (result == -ESTALE) {
		/* nd->path had been dropped */
		current->total_link_count = 0;
	return link_path_walk(name, nd);
		nd->path = save;
		path_get(&nd->path);
		nd->flags |= LOOKUP_REVAL;
		result = link_path_walk(name, nd);
	}

	path_put(&save);

	return result;
}

static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
@@ -1649,7 +1639,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
	struct file *filp;
	struct nameidata nd;
	int error;
	struct path path;
	struct path path, save;
	struct dentry *dir;
	int count = 0;
	int will_write;
@@ -1862,7 +1852,17 @@ 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