patch-2.1.61 linux/fs/namei.c

Next file: linux/fs/nfs/dir.c
Previous file: linux/fs/isofs/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.60/linux/fs/namei.c linux/fs/namei.c
@@ -237,8 +237,7 @@
 			int error = dir->i_op->lookup(dir, dentry);
 			result = ERR_PTR(error);
 			if (!error)
-				result = dget(dentry->d_mounts);
-			dput(dentry);
+				result = dentry;
 		}
 	}
 	up(&dir->i_sem);
@@ -293,25 +292,6 @@
 	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;
@@ -334,6 +314,18 @@
 	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.
  *
@@ -415,9 +407,19 @@
 			}
 		}
 
-		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;

FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]