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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d6d95ded91
commit
e3c1392808
1 changed files with 24 additions and 32 deletions
56
fs/namei.c
56
fs/namei.c
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue