From: Jan Blunck <jblunck@xxxxxxx> This patch changes real_lookup() into returning a struct path. Signed-off-by: Jan Blunck <jblunck@xxxxxxx> Signed-off-by: Valerie Aurora <vaurora@xxxxxxxxxx> Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx> --- fs/namei.c | 82 +++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 51 insertions(+), 31 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0ddfefb..3f645ce 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -473,10 +473,11 @@ ok: * make sure that nobody added the entry to the dcache in the meantime.. * SMP-safe */ -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, struct nameidata *nd) +static int real_lookup(struct nameidata *nd, struct qstr *name, + struct path *path) { - struct dentry * result; - struct inode *dir = parent->d_inode; + struct inode *dir = nd->path.dentry->d_inode; + int res = 0; mutex_lock(&dir->i_mutex); /* @@ -493,27 +494,36 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s * * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup */ - result = d_lookup(parent, name); - if (!result) { + path->dentry = d_lookup(nd->path.dentry, name); + path->mnt = nd->path.mnt; + if (!path->dentry) { struct dentry *dentry; /* Don't create child dentry for a dead directory. */ - result = ERR_PTR(-ENOENT); - if (IS_DEADDIR(dir)) + if (IS_DEADDIR(dir)) { + res = -ENOENT; goto out_unlock; + } - dentry = d_alloc(parent, name); - result = ERR_PTR(-ENOMEM); + dentry = d_alloc(nd->path.dentry, name); if (dentry) { - result = dir->i_op->lookup(dir, dentry, nd); - if (result) + path->dentry = dir->i_op->lookup(dir, dentry, nd); + if (path->dentry) { dput(dentry); - else - result = dentry; + if (IS_ERR(path->dentry)) { + res = PTR_ERR(path->dentry); + path->dentry = NULL; + path->mnt = NULL; + } + } else + path->dentry = dentry; + } else { + res = -ENOMEM; + path->mnt = NULL; } out_unlock: mutex_unlock(&dir->i_mutex); - return result; + return res; } /* @@ -521,12 +531,20 @@ out_unlock: * we waited on the semaphore. Need to revalidate. */ mutex_unlock(&dir->i_mutex); - if (result->d_op && result->d_op->d_revalidate) { - result = do_revalidate(result, nd); - if (!result) - result = ERR_PTR(-ENOENT); + if (path->dentry->d_op && path->dentry->d_op->d_revalidate) { + path->dentry = do_revalidate(path->dentry, nd); + if (!path->dentry) { + res = -ENOENT; + path->mnt = NULL; + } + if (IS_ERR(path->dentry)) { + res = PTR_ERR(path->dentry); + path->dentry = NULL; + path->mnt = NULL; + } } - return result; + + return res; } /* @@ -793,35 +811,37 @@ static __always_inline void follow_dotdot(struct nameidata *nd) static int do_lookup(struct nameidata *nd, struct qstr *name, struct path *path) { - struct vfsmount *mnt = nd->path.mnt; - struct dentry *dentry = __d_lookup(nd->path.dentry, name); + int err; - if (!dentry) + path->dentry = __d_lookup(nd->path.dentry, name); + path->mnt = nd->path.mnt; + if (!path->dentry) goto need_lookup; - if (dentry->d_op && dentry->d_op->d_revalidate) + if (path->dentry->d_op && path->dentry->d_op->d_revalidate) goto need_revalidate; + done: - path->mnt = mnt; - path->dentry = dentry; __follow_mount(path); return 0; need_lookup: - dentry = real_lookup(nd->path.dentry, name, nd); - if (IS_ERR(dentry)) + err = real_lookup(nd, name, path); + if (err) goto fail; goto done; need_revalidate: - dentry = do_revalidate(dentry, nd); - if (!dentry) + path->dentry = do_revalidate(path->dentry, nd); + if (!path->dentry) goto need_lookup; - if (IS_ERR(dentry)) + if (IS_ERR(path->dentry)) { + err = PTR_ERR(path->dentry); goto fail; + } goto done; fail: - return PTR_ERR(dentry); + return err; } /* -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html