Hi,

On Sat, Nov 07, 2009 at 05:23:12PM +0530, Saifi Khan wrote:
> After about 8 hrs of uptime on the X86_64 build, the system had
> an assertion failure.
> 
>  assertion: parent != NULL in hammer_cursor_removed_node

Although the backtrace is garbled, this is most likely the panic
introduced by the committed fix for http://bugs.dragonflybsd.org/issue1577,
especially since it happened while running `hammer cleanup' from
a periodic(8) job.
For some reason the search facility on our bug tracker can't find it
with a keyword like `hammer_cursor_removed_node' even with full text search.

The commit f3a4893b has moved the call to hammer_cursor_removed_node()
in btree_remove() to after the recursive call to itself, but a call to
btree_remove() moves the cursor up after deleting the sub tree, so it's
possible that it reaches the root of the tree during the recursion.
When that happens, cursor->parent is set to NULL and ondisk->parent of
the current node is also 0.

I have a bandaid for this problem (it's being tested):

HAMMER VFS - don't call hammer_cursor_removed_node when the recursion reached 
the root of the filesystem

---
 sys/vfs/hammer/hammer_btree.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/sys/vfs/hammer/hammer_btree.c b/sys/vfs/hammer/hammer_btree.c
index 6ee1e1a..551fb5f 100644
--- a/sys/vfs/hammer/hammer_btree.c
+++ b/sys/vfs/hammer/hammer_btree.c
@@ -2226,9 +2226,15 @@ btree_remove(hammer_cursor_t cursor)
                        hammer_cursor_deleted_element(cursor->node, 0);
                        error = btree_remove(cursor);
                        if (error == 0) {
-                               hammer_cursor_removed_node(
-                                       node, cursor->parent,
-                                       cursor->parent_index);
+                               KKASSERT(
+                                       cursor->parent != NULL ||
+                                       cursor->node->ondisk->parent == 0
+                               );
+                               if (cursor->parent != NULL) {
+                                       hammer_cursor_removed_node(
+                                               node, cursor->parent,
+                                               cursor->parent_index);
+                               }
                                hammer_modify_node_all(cursor->trans, node);
                                ondisk = node->ondisk;
                                ondisk->type = HAMMER_BTREE_TYPE_DELETED;
-- 
1.6.4

Reply via email to