summaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /fs/namei.c
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c66
1 files changed, 38 insertions, 28 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 54714754d..242363824 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -232,11 +232,15 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
result = d_lookup(parent, name);
if (!result) {
struct dentry * dentry = d_alloc(parent, name);
- int error = dir->i_op->lookup(dir, dentry);
- result = ERR_PTR(error);
- if (!error)
- result = dget(dentry->d_mounts);
- dput(dentry);
+ result = ERR_PTR(-ENOMEM);
+ if (dentry) {
+ int error = dir->i_op->lookup(dir, dentry);
+ result = dentry;
+ if (error) {
+ dput(dentry);
+ result = ERR_PTR(error);
+ }
+ }
}
up(&dir->i_sem);
return result;
@@ -290,25 +294,6 @@ static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * nam
return dget(result);
}
-/* In difference to the former version, lookup() no longer eats the dir. */
-static inline struct dentry * lookup(struct dentry * dir, struct qstr * name)
-{
- struct dentry * result;
-
- result = reserved_lookup(dir, name);
- if (result)
- goto done;
-
- result = cached_lookup(dir, name);
- if (result)
- goto done;
-
- result = real_lookup(dir, name);
-
-done:
- return result;
-}
-
static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry)
{
struct inode * inode = dentry->d_inode;
@@ -331,6 +316,18 @@ static struct dentry * do_follow_link(struct dentry *base, struct dentry *dentry
return dentry;
}
+static inline struct dentry * follow_mount(struct dentry * dentry)
+{
+ struct dentry * mnt = dentry->d_mounts;
+
+ if (mnt != dentry) {
+ dget(mnt);
+ dput(dentry);
+ dentry = mnt;
+ }
+ return dentry;
+}
+
/*
* Name resolution.
*
@@ -412,9 +409,19 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
}
}
- dentry = lookup(base, &this);
- if (IS_ERR(dentry))
- break;
+ /* This does the actual lookups.. */
+ dentry = reserved_lookup(base, &this);
+ if (!dentry) {
+ dentry = cached_lookup(base, &this);
+ if (!dentry) {
+ dentry = real_lookup(base, &this);
+ if (IS_ERR(dentry))
+ break;
+ }
+ }
+
+ /* Check mountpoints.. */
+ dentry = follow_mount(dentry);
if (!follow)
break;
@@ -445,6 +452,7 @@ struct dentry * __namei(const char *pathname, int follow_link)
char *name;
struct dentry *dentry;
+ check_dcache_memory();
name = getname(pathname);
dentry = (struct dentry *) name;
if (!IS_ERR(name)) {
@@ -518,6 +526,7 @@ struct dentry * open_namei(const char * pathname, int flag, int mode)
struct inode *inode;
struct dentry *dentry;
+ check_dcache_memory();
mode &= S_IALLUGO & ~current->fs->umask;
mode |= S_IFREG;
@@ -1170,7 +1179,8 @@ static inline int do_rename(const char * oldname, const char * newname)
if (new_dir->d_inode->i_sb && new_dir->d_inode->i_sb->dq_op)
new_dir->d_inode->i_sb->dq_op->initialize(new_dir->d_inode, -1);
- error = old_dir->d_inode->i_op->rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry);
+ error = old_dir->d_inode->i_op->rename(old_dir->d_inode, old_dentry,
+ new_dir->d_inode, new_dentry);
exit_lock:
double_unlock(new_dir, old_dir);