patch-2.3.99-pre7 linux/fs/dcache.c

Next file: linux/fs/devfs/base.c
Previous file: linux/fs/cramfs/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre6/linux/fs/dcache.c linux/fs/dcache.c
@@ -337,25 +337,27 @@
 	}
 }
 
+/*
+ * Search for at least 1 mount point in the dentry's subdirs.
+ * We descend to the next level whenever the d_subdirs
+ * list is non-empty and continue searching.
+ */
+ 
 /**
- * is_root_busy - check if a root dentry could be freed
- * @root: Dentry to work down from
- *
- * Check whether a root dentry would be in use if all of its
- * child dentries were freed. This allows a non-destructive
- * test for unmounting a device.
+ * have_submounts - check for mounts over a dentry
+ * @parent: dentry to check.
  *
- * Return non zero if the root is still busy.
+ * Return true if the parent or its subdirectories contain
+ * a mount point
  */
  
-int is_root_busy(struct dentry *root)
+int have_submounts(struct dentry *parent)
 {
-	struct dentry *this_parent = root;
+	struct dentry *this_parent = parent;
 	struct list_head *next;
-	int count = root->d_count;
-
-	check_lock();
 
+	if (d_mountpoint(parent))
+		return 1;
 repeat:
 	next = this_parent->d_subdirs.next;
 resume:
@@ -363,48 +365,31 @@
 		struct list_head *tmp = next;
 		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
 		next = tmp->next;
-		/* Decrement count for unused children */
-		count += (dentry->d_count - 1);
+		/* Have we found a mount point ? */
+		if (d_mountpoint(dentry))
+			return 1;
 		if (!list_empty(&dentry->d_subdirs)) {
 			this_parent = dentry;
 			goto repeat;
 		}
-		/* root is busy if any leaf is busy */
-		if (dentry->d_count)
-			return 1;
 	}
 	/*
 	 * All done at this level ... ascend and resume the search.
 	 */
-	if (this_parent != root) {
+	if (this_parent != parent) {
 		next = this_parent->d_child.next; 
 		this_parent = this_parent->d_parent;
 		goto resume;
 	}
-	return (count > 1); /* remaining users? */
+	return 0; /* No mount points found in tree */
 }
 
-/*
- * Search for at least 1 mount point in the dentry's subdirs.
- * We descend to the next level whenever the d_subdirs
- * list is non-empty and continue searching.
- */
- 
-/**
- * have_submounts - check for mounts over a dentry
- * @parent: dentry to check.
- *
- * Return true if the parent or its subdirectories contain
- * a mount point
- */
- 
-int have_submounts(struct dentry *parent)
+int d_active_refs(struct dentry *root)
 {
-	struct dentry *this_parent = parent;
+	struct dentry *this_parent = root;
 	struct list_head *next;
+	int count = root->d_count;
 
-	if (d_mountpoint(parent))
-		return 1;
 repeat:
 	next = this_parent->d_subdirs.next;
 resume:
@@ -412,9 +397,8 @@
 		struct list_head *tmp = next;
 		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
 		next = tmp->next;
-		/* Have we found a mount point ? */
-		if (d_mountpoint(dentry))
-			return 1;
+		/* Decrement count for unused children */
+		count += (dentry->d_count - 1);
 		if (!list_empty(&dentry->d_subdirs)) {
 			this_parent = dentry;
 			goto repeat;
@@ -423,12 +407,12 @@
 	/*
 	 * All done at this level ... ascend and resume the search.
 	 */
-	if (this_parent != parent) {
+	if (this_parent != root) {
 		next = this_parent->d_child.next; 
 		this_parent = this_parent->d_parent;
 		goto resume;
 	}
-	return 0; /* No mount points found in tree */
+	return count;
 }
 
 /*
@@ -511,7 +495,7 @@
  *  ...
  *   6 - base-level: try to shrink a bit.
  */
-int shrink_dcache_memory(int priority, unsigned int gfp_mask, zone_t * zone)
+int shrink_dcache_memory(int priority, unsigned int gfp_mask)
 {
 	int count = 0;
 	lock_kernel();
@@ -574,8 +558,7 @@
 	} else
 		INIT_LIST_HEAD(&dentry->d_child);
 		
-	dentry->d_mounts = dentry;
-	dentry->d_covers = dentry;
+	INIT_LIST_HEAD(&dentry->d_vfsmnt);
 	INIT_LIST_HEAD(&dentry->d_hash);
 	INIT_LIST_HEAD(&dentry->d_lru);
 	INIT_LIST_HEAD(&dentry->d_subdirs);
@@ -895,6 +878,7 @@
 {
 	char * end = buffer+buflen;
 	char * retval;
+	int namelen;
 
 	*--end = '\0';
 	buflen--;
@@ -910,14 +894,18 @@
 
 	for (;;) {
 		struct dentry * parent;
-		int namelen;
 
-		if (dentry == root)
+		if (dentry == root && vfsmnt == rootmnt)
 			break;
-		dentry = dentry->d_covers;
+		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+			/* Global root? */
+			if (vfsmnt->mnt_parent == vfsmnt)
+				goto global_root;
+			dentry = vfsmnt->mnt_mountpoint;
+			vfsmnt = vfsmnt->mnt_parent;
+			continue;
+		}
 		parent = dentry->d_parent;
-		if (dentry == parent)
-			break;
 		namelen = dentry->d_name.len;
 		buflen -= namelen + 1;
 		if (buflen < 0)
@@ -929,6 +917,14 @@
 		dentry = parent;
 	}
 	return retval;
+global_root:
+	namelen = dentry->d_name.len;
+	buflen -= namelen;
+	if (buflen >= 0) {
+		end -= namelen;
+		memcpy(end, dentry->d_name.name, namelen);
+	}
+	return end;
 }
 
 /*
@@ -1100,10 +1096,11 @@
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (dentry_hashtable == NULL && --order >= 0);
 
+	printk("Dentry-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+			nr_hash, order, (PAGE_SIZE << order));
+
 	if (!dentry_hashtable)
 		panic("Failed to allocate dcache hash table\n");
-
-	printk("VFS: DCACHE hash table configured to %d entries\n", nr_hash);
 
 	d = dentry_hashtable;
 	i = nr_hash;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)