+ while (1) {
+ // Prepare for non-recursive in-order traversal of the red-black
+ // tree of this dentry's children
+
+ while (node) {
+ // Push this node to the sibling stack and examine the
+ // left neighbor, if any
+ list_add(&rbnode_dentry(node)->tmp_list, &sibling_stack);
+ node = node->rb_left;
+ }
+
+ next_sibling = sibling_stack.next;
+ if (next_sibling == sibling_stack_bottom) {
+ // Done with all siblings. Pop the main dentry to move
+ // back up one level.
+ main_dentry = container_of(main_stack.next,
+ struct dentry,
+ tmp_list);
+ list_del(&main_dentry->tmp_list);
+
+ if (main_dentry == root)
+ goto out;
+
+ // Restore sibling stack bottom from the previous level
+ sibling_stack_bottom = (void*)main_dentry->parent;
+
+ // Restore the just-popped main dentry's parent
+ main_dentry->parent = container_of(main_stack.next,
+ struct dentry,
+ tmp_list);
+
+ // The next sibling to traverse in the previous level,
+ // in the in-order traversal of the red-black tree, is
+ // the one to the right.
+ node = main_dentry->rb_node.rb_right;
+ } else {
+ // The sibling stack is not empty, so there are more to
+ // go!
+
+ // Pop a sibling from the stack.
+ list_del(next_sibling);
+ dentry = container_of(next_sibling, struct dentry, tmp_list);
+
+ // Visit the sibling.
+ ret = visitor(dentry, arg);
+ if (ret != 0) {
+ // Failed. Restore parent pointers for the
+ // dentries in the main stack
+ list_for_each_entry(dentry, &main_stack, tmp_list) {
+ dentry->parent = container_of(dentry->tmp_list.next,
+ struct dentry,
+ tmp_list);
+ }
+ goto out;
+ }
+
+ // We'd like to recursively visit the dentry tree rooted
+ // at this sibling. To do this, add it to the main
+ // stack, save the bottom of this level's sibling stack
+ // in the dentry->parent field, re-set the bottom of the
+ // sibling stack to be its current height, and set
+ // main_dentry to the sibling so it becomes the parent
+ // dentry in the next iteration through the outer loop.
+ if (inode_has_children(dentry->d_inode)) {
+ list_add(&dentry->tmp_list, &main_stack);
+ dentry->parent = (void*)sibling_stack_bottom;
+ sibling_stack_bottom = sibling_stack.next;
+
+ main_dentry = dentry;
+ node = main_dentry->d_inode->children.rb_node;
+ } else {
+ node = dentry->rb_node.rb_right;
+ }
+ }
+ }
+out:
+ root->parent = root;
+ return ret;
+#endif