mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-25 08:34:31 +00:00
namei: teach lookup_slow() to skip revalidate
... and make mountpoint_last() use it. That makes all candidates for lookup with parent locked shared go through lookup_slow(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
e3c1392808
commit
949a852e46
2 changed files with 36 additions and 23 deletions
58
fs/namei.c
58
fs/namei.c
|
@ -1605,7 +1605,29 @@ static struct dentry *lookup_slow(const struct qstr *name,
|
||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
inode_lock(dir->d_inode);
|
inode_lock(dir->d_inode);
|
||||||
dentry = __lookup_hash(name, dir, flags);
|
dentry = d_lookup(dir, name);
|
||||||
|
if (unlikely(dentry)) {
|
||||||
|
if ((dentry->d_flags & DCACHE_OP_REVALIDATE) &&
|
||||||
|
!(flags & LOOKUP_NO_REVAL)) {
|
||||||
|
int error = d_revalidate(dentry, flags);
|
||||||
|
if (unlikely(error <= 0)) {
|
||||||
|
if (!error)
|
||||||
|
d_invalidate(dentry);
|
||||||
|
dput(dentry);
|
||||||
|
dentry = ERR_PTR(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dentry) {
|
||||||
|
inode_unlock(dir->d_inode);
|
||||||
|
return dentry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dentry = d_alloc(dir, name);
|
||||||
|
if (unlikely(!dentry)) {
|
||||||
|
inode_unlock(dir->d_inode);
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
|
dentry = lookup_real(dir->d_inode, dentry, flags);
|
||||||
inode_unlock(dir->d_inode);
|
inode_unlock(dir->d_inode);
|
||||||
return dentry;
|
return dentry;
|
||||||
}
|
}
|
||||||
|
@ -2425,31 +2447,21 @@ mountpoint_last(struct nameidata *nd, struct path *path)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
dentry = dget(nd->path.dentry);
|
dentry = dget(nd->path.dentry);
|
||||||
goto done;
|
} else {
|
||||||
}
|
dentry = d_lookup(dir, &nd->last);
|
||||||
|
|
||||||
inode_lock(dir->d_inode);
|
|
||||||
dentry = d_lookup(dir, &nd->last);
|
|
||||||
if (!dentry) {
|
|
||||||
/*
|
|
||||||
* No cached dentry. Mounted dentries are pinned in the cache,
|
|
||||||
* so that means that this dentry is probably a symlink or the
|
|
||||||
* path doesn't actually point to a mounted dentry.
|
|
||||||
*/
|
|
||||||
dentry = d_alloc(dir, &nd->last);
|
|
||||||
if (!dentry) {
|
if (!dentry) {
|
||||||
inode_unlock(dir->d_inode);
|
/*
|
||||||
return -ENOMEM;
|
* No cached dentry. Mounted dentries are pinned in the
|
||||||
}
|
* cache, so that means that this dentry is probably
|
||||||
dentry = lookup_real(dir->d_inode, dentry, nd->flags);
|
* a symlink or the path doesn't actually point
|
||||||
if (IS_ERR(dentry)) {
|
* to a mounted dentry.
|
||||||
inode_unlock(dir->d_inode);
|
*/
|
||||||
return PTR_ERR(dentry);
|
dentry = lookup_slow(&nd->last, dir,
|
||||||
|
nd->flags | LOOKUP_NO_REVAL);
|
||||||
|
if (IS_ERR(dentry))
|
||||||
|
return PTR_ERR(dentry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inode_unlock(dir->d_inode);
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (d_is_negative(dentry)) {
|
if (d_is_negative(dentry)) {
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
|
||||||
#define LOOKUP_PARENT 0x0010
|
#define LOOKUP_PARENT 0x0010
|
||||||
#define LOOKUP_REVAL 0x0020
|
#define LOOKUP_REVAL 0x0020
|
||||||
#define LOOKUP_RCU 0x0040
|
#define LOOKUP_RCU 0x0040
|
||||||
|
#define LOOKUP_NO_REVAL 0x0080
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intent data
|
* Intent data
|
||||||
|
|
Loading…
Add table
Reference in a new issue