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

Commit e3c13928 authored by Al Viro's avatar Al Viro
Browse files

namei: massage lookup_slow() to be usable by lookup_one_len_unlocked()



Return dentry and don't pass nameidata or path; lift crossing mountpoints
into the caller.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent d6d95ded
Loading
Loading
Loading
Loading
+24 −32
Original line number Diff line number Diff line
@@ -1445,7 +1445,8 @@ static int follow_dotdot(struct nameidata *nd)
 * allocates a new one if not found or not valid.  In the need_lookup argument
 * returns whether i_op->lookup is necessary.
 */
static struct dentry *lookup_dcache(struct qstr *name, struct dentry *dir,
static struct dentry *lookup_dcache(const struct qstr *name,
				    struct dentry *dir,
				    unsigned int flags)
{
	struct dentry *dentry;
@@ -1491,7 +1492,7 @@ static struct dentry *lookup_real(struct inode *dir, struct dentry *dentry,
	return dentry;
}

static struct dentry *__lookup_hash(struct qstr *name,
static struct dentry *__lookup_hash(const struct qstr *name,
		struct dentry *base, unsigned int flags)
{
	struct dentry *dentry = lookup_dcache(name, base, flags);
@@ -1598,21 +1599,15 @@ static int lookup_fast(struct nameidata *nd,
}

/* Fast lookup failed, do it the slow way */
static int lookup_slow(struct nameidata *nd, struct path *path)
static struct dentry *lookup_slow(const struct qstr *name,
				  struct dentry *dir,
				  unsigned int flags)
{
	struct dentry *dentry, *parent;

	parent = nd->path.dentry;
	BUG_ON(nd->inode != parent->d_inode);

	inode_lock(parent->d_inode);
	dentry = __lookup_hash(&nd->last, parent, nd->flags);
	inode_unlock(parent->d_inode);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);
	path->mnt = nd->path.mnt;
	path->dentry = dentry;
	return follow_managed(path, nd);
	struct dentry *dentry;
	inode_lock(dir->d_inode);
	dentry = __lookup_hash(name, dir, flags);
	inode_unlock(dir->d_inode);
	return dentry;
}

static inline int may_lookup(struct nameidata *nd)
@@ -1719,15 +1714,20 @@ static int walk_component(struct nameidata *nd, int flags)
	if (unlikely(err <= 0)) {
		if (err < 0)
			return err;

		err = lookup_slow(nd, &path);
		if (err < 0)
		path.dentry = lookup_slow(&nd->last, nd->path.dentry,
					  nd->flags);
		if (IS_ERR(path.dentry))
			return PTR_ERR(path.dentry);
		if (unlikely(d_is_negative(path.dentry))) {
			dput(path.dentry);
			return -ENOENT;
		}
		path.mnt = nd->path.mnt;
		err = follow_managed(&path, nd);
		if (unlikely(err < 0))
			return err;

		seq = 0;	/* we are already out of RCU mode */
		err = -ENOENT;
		if (d_is_negative(path.dentry))
			goto out_path_put;
		inode = d_backing_inode(path.dentry);
	}

@@ -1740,10 +1740,6 @@ static int walk_component(struct nameidata *nd, int flags)
	nd->inode = inode;
	nd->seq = seq;
	return 0;

out_path_put:
	path_to_nameidata(&path, nd);
	return err;
}

/*
@@ -2350,12 +2346,8 @@ struct dentry *lookup_one_len_unlocked(const char *name,
		return ERR_PTR(err);

	ret = lookup_dcache(&this, base, 0);
	if (ret)
		return ret;

	inode_lock(base->d_inode);
	ret =  __lookup_hash(&this, base, 0);
	inode_unlock(base->d_inode);
	if (!ret)
		ret = lookup_slow(&this, base, 0);
	return ret;
}
EXPORT_SYMBOL(lookup_one_len_unlocked);