[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 |