Updated "is_root_busy" for fs/dcache.c

Bill Hawes (whawes@star.net)
Fri, 24 Jul 1998 09:40:32 -0400


This is a multi-part message in MIME format.
--------------5C3D8B68C02FAD100AB670E5
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

The attached patch against 2.1.110 corrects a problem with the use
counting in the previous "is_root_busy" patch. The "is_root_busy"
routine will enable autofs (and possible other automount utilities) to
determine non-destructively whether a volume can be unmounted.

The is_root_busy test should probably be performed before attempting the
new umount_begin calls, as there have been problem reports with NFS if
the umount is started while write operations are in flight.

Regards,
Bill
--------------5C3D8B68C02FAD100AB670E5
Content-Type: text/plain; charset=us-ascii; name="dcache_110-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dcache_110-patch"

--- linux-2.1.110/include/linux/dcache.h.old Sun May 17 12:19:38 1998
+++ linux-2.1.110/include/linux/dcache.h Tue Jul 21 17:47:17 1998
@@ -138,6 +138,9 @@
/* only used at mount-time */
extern struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root);

+/* test whether root is busy without destroying dcache */
+extern int is_root_busy(struct dentry *);
+
/*
* This adds the entry to the hash queues and initializes "d_inode".
* The entry was actually filled in earlier during "d_alloc()"
--- linux-2.1.110/fs/dcache.c.old Tue Jul 21 14:41:46 1998
+++ linux-2.1.110/fs/dcache.c Wed Jul 22 07:47:36 1998
@@ -363,6 +403,45 @@
}

/*
+ * 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.
+ */
+int is_root_busy(struct dentry *root)
+{
+ struct dentry *this_parent = root;
+ struct list_head *next;
+ int count = root->d_count;
+
+repeat:
+ next = this_parent->d_subdirs.next;
+resume:
+ while (next != &this_parent->d_subdirs) {
+ 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);
+ 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) {
+ next = this_parent->d_child.next;
+ this_parent = this_parent->d_parent;
+ goto resume;
+ }
+ return (count == 1); /* one remaining use count? */
+}
+
+/*
* Search the dentry child list for the specified parent,
* and move any unused dentries to the end of the unused
* list for prune_dcache(). We descend to the next level
--- linux-2.1.110/kernel/ksyms.c.old Tue Jul 21 14:41:49 1998
+++ linux-2.1.110/kernel/ksyms.c Wed Jul 22 11:24:29 1998
@@ -184,6 +187,7 @@
EXPORT_SYMBOL(dput);
EXPORT_SYMBOL(get_cached_page);
EXPORT_SYMBOL(put_cached_page);
+EXPORT_SYMBOL(is_root_busy);
EXPORT_SYMBOL(prune_dcache);
EXPORT_SYMBOL(shrink_dcache_sb);
EXPORT_SYMBOL(shrink_dcache_parent);

--------------5C3D8B68C02FAD100AB670E5--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html