Skip to content

Commit

Permalink
untangling do_lookup() - switch to calling __lookup_hash()
Browse files Browse the repository at this point in the history
now we have __lookup_hash() open-coded if !dentry case;
just call the damn thing instead...

Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Mar 31, 2012
1 parent a6ecdfc commit a325554
Showing 1 changed file with 46 additions and 67 deletions.
113 changes: 46 additions & 67 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,51 @@ static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentr
return dentry;
}

static struct dentry *__lookup_hash(struct qstr *name,
struct dentry *base, struct nameidata *nd)
{
struct dentry *dentry;

/*
* Don't bother with __d_lookup: callers are for creat as
* well as unlink, so a lot of the time it would cost
* a double lookup.
*/
dentry = d_lookup(base, name);

if (dentry && d_need_lookup(dentry)) {
/*
* __lookup_hash is called with the parent dir's i_mutex already
* held, so we are good to go here.
*/
return d_inode_lookup(base, dentry, nd);
}

if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) {
int status = d_revalidate(dentry, nd);
if (unlikely(status <= 0)) {
/*
* The dentry failed validation.
* If d_revalidate returned 0 attempt to invalidate
* the dentry otherwise d_revalidate is asking us
* to return a fail status.
*/
if (status < 0) {
dput(dentry);
return ERR_PTR(status);
} else if (!d_invalidate(dentry)) {
dput(dentry);
dentry = NULL;
}
}
}

if (!dentry)
dentry = d_alloc_and_lookup(base, name, nd);

return dentry;
}

/*
* It's more convoluted than I'd like it to be, but... it's still fairly
* small and for now I'd prefer to have fast path as straight as possible.
Expand Down Expand Up @@ -1173,28 +1218,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
BUG_ON(nd->inode != dir);

mutex_lock(&dir->i_mutex);
dentry = d_lookup(parent, name);
if (dentry && d_need_lookup(dentry)) {
dentry = d_inode_lookup(parent, dentry, nd);
goto l;
}
if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) {
status = d_revalidate(dentry, nd);
if (unlikely(status <= 0)) {
if (status < 0) {
dput(dentry);
dentry = ERR_PTR(status);
goto l;
}
if (!d_invalidate(dentry)) {
dput(dentry);
dentry = NULL;
}
}
}
if (!dentry)
dentry = d_alloc_and_lookup(parent, name, nd);
l:
dentry = __lookup_hash(name, parent, nd);
mutex_unlock(&dir->i_mutex);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
Expand Down Expand Up @@ -1850,51 +1874,6 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
return err;
}

static struct dentry *__lookup_hash(struct qstr *name,
struct dentry *base, struct nameidata *nd)
{
struct dentry *dentry;

/*
* Don't bother with __d_lookup: callers are for creat as
* well as unlink, so a lot of the time it would cost
* a double lookup.
*/
dentry = d_lookup(base, name);

if (dentry && d_need_lookup(dentry)) {
/*
* __lookup_hash is called with the parent dir's i_mutex already
* held, so we are good to go here.
*/
return d_inode_lookup(base, dentry, nd);
}

if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) {
int status = d_revalidate(dentry, nd);
if (unlikely(status <= 0)) {
/*
* The dentry failed validation.
* If d_revalidate returned 0 attempt to invalidate
* the dentry otherwise d_revalidate is asking us
* to return a fail status.
*/
if (status < 0) {
dput(dentry);
return ERR_PTR(status);
} else if (!d_invalidate(dentry)) {
dput(dentry);
dentry = NULL;
}
}
}

if (!dentry)
dentry = d_alloc_and_lookup(base, name, nd);

return dentry;
}

/*
* Restricted form of lookup. Doesn't follow links, single-component only,
* needs parent already locked. Doesn't follow mounts.
Expand Down

0 comments on commit a325554

Please sign in to comment.