[Libsysio-commit] HEAD: libsysio/src inode.c
Brought to you by:
lward
|
From: Lee W. <lw...@us...> - 2003-09-09 04:23:31
|
Update of /cvsroot/libsysio/libsysio/src
In directory sc8-pr-cvs1:/tmp/cvs-serv19786/src
Modified Files:
inode.c
Log Message:
Jim Schutt found a bug where orphaned path base nodes were not being reclaimed.
This would manifest itself with an abort on a busy inode during FS unmount.
He presented it this way...
./test_copy -r /tmp/jaschut tst.dat tst2.dat
I altered _sysio_p_prune to check for path base nodes that have no aliases.
If found, a new routine called _sysio_prune is called. This just descends
the given sub-tree releasing orphaned path-base nodes.
Index: inode.c
===================================================================
RCS file: /cvsroot/libsysio/libsysio/src/inode.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -b -B -p -r1.9 -r1.10
--- inode.c 26 Aug 2003 15:53:59 -0000 1.9
+++ inode.c 8 Sep 2003 15:43:21 -0000 1.10
@@ -606,6 +606,30 @@ _sysio_p_find_alias(struct pnode *parent
}
/*
+ * Prune idle path base nodes freom the passed sub-tree, including the root.
+ */
+static void
+_sysio_prune(struct pnode_base *rpb)
+{
+ struct pnode_base *nxtpb, *pb;
+
+ nxtpb = rpb->pb_children.lh_first;
+ while ((pb = nxtpb)) {
+ nxtpb = pb->pb_sibs.le_next;
+ if (pb->pb_aliases.lh_first)
+ continue;
+ if (pb->pb_children.lh_first) {
+ _sysio_prune(pb);
+ continue;
+ }
+ _sysio_pb_gone(pb);
+ }
+ if (rpb->pb_children.lh_first)
+ return;
+ _sysio_pb_gone(rpb);
+}
+
+/*
* Prune idle nodes from the passed sub-tree, including the root.
*
* Returns the number of aliases on the same mount that could not be pruned.
@@ -623,6 +647,10 @@ _sysio_p_prune(struct pnode *root)
while ((pb = nxtpb)) {
nxtpb = pb->pb_sibs.le_next;
nxtpno = pb->pb_aliases.lh_first;
+ if (!nxtpno) {
+ _sysio_prune(pb);
+ continue;
+ }
while ((pno = nxtpno)) {
nxtpno = pno->p_links.le_next;
if (pno->p_mount != root->p_mount) {
@@ -664,10 +692,10 @@ _sysio_p_prune(struct pnode *root)
if (_sysio_do_unmount(pno->p_mount) != 0) {
P_RELE(pno);
count++;
- continue;
}
+ continue;
#endif
- } else
+ }
_sysio_p_gone(pno);
}
}
@@ -682,9 +710,9 @@ _sysio_p_prune(struct pnode *root)
/*
* All that is left is the root. Try for it too.
*/
- if (root->p_ref)
+ if (root->p_ref) {
count++;
- else if (root->p_mount->mnt_root == root) {
+ } else if (root->p_mount->mnt_root == root) {
#ifndef AUTOMOUNT_FILE_NAME
count++;
#else
|