return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
 }
 
+#define RADIX_TREE_RETRY       ptr_to_indirect(NULL)
+
 #ifdef CONFIG_RADIX_TREE_MULTIORDER
 /* Sibling slots point directly to another slot in the same node */
 static inline bool is_sibling_entry(struct radix_tree_node *parent, void *node)
                slot = to_free->slots[0];
                if (!slot)
                        break;
+               if (!radix_tree_is_indirect_ptr(slot) && (root->height > 1))
+                       break;
+
+               if (radix_tree_is_indirect_ptr(slot)) {
+                       slot = indirect_to_ptr(slot);
+                       slot->parent = NULL;
+                       slot = ptr_to_indirect(slot);
+               }
 
                /*
                 * We don't need rcu_assign_pointer(), since we are simply
                 * (to_free->slots[0]), it will be safe to dereference the new
                 * one (root->rnode) as far as dependent read barriers go.
                 */
-               if (root->height > 1) {
-                       if (!radix_tree_is_indirect_ptr(slot))
-                               break;
-
-                       slot = indirect_to_ptr(slot);
-                       slot->parent = NULL;
-                       slot = ptr_to_indirect(slot);
-               }
                root->rnode = slot;
                root->height--;
 
                 * also results in a stale slot). So tag the slot as indirect
                 * to force callers to retry.
                 */
-               if (root->height == 0)
-                       *((unsigned long *)&to_free->slots[0]) |=
-                                               RADIX_TREE_INDIRECT_PTR;
+               if (!radix_tree_is_indirect_ptr(slot))
+                       to_free->slots[0] = RADIX_TREE_RETRY;
 
                radix_tree_node_free(to_free);
        }
 
                item_check_absent(&tree, i);
 }
 
+static void multiorder_shrink(unsigned long index, int order)
+{
+       unsigned long i;
+       unsigned long max = 1 << order;
+       RADIX_TREE(tree, GFP_KERNEL);
+       struct radix_tree_node *node;
+
+       printf("Multiorder shrink index %ld, order %d\n", index, order);
+
+       assert(item_insert_order(&tree, 0, order) == 0);
+
+       node = tree.rnode;
+
+       assert(item_insert(&tree, index) == 0);
+       assert(node != tree.rnode);
+
+       assert(item_delete(&tree, index) != 0);
+       assert(node == tree.rnode);
+
+       for (i = 0; i < max; i++) {
+               struct item *item = item_lookup(&tree, i);
+               assert(item != 0);
+               assert(item->index == 0);
+       }
+       for (i = max; i < 2*max; i++)
+               item_check_absent(&tree, i);
+
+       if (!item_delete(&tree, 0)) {
+               printf("failed to delete index %ld (order %d)\n", index, order);                abort();
+       }
+
+       for (i = 0; i < 2*max; i++)
+               item_check_absent(&tree, i);
+}
+
 void multiorder_checks(void)
 {
        int i;
                multiorder_check(0, i);
                multiorder_check((1UL << i) + 1, i);
        }
+
+       for (i = 0; i < 15; i++)
+               multiorder_shrink((1UL << (i + RADIX_TREE_MAP_SHIFT)), i);
+
 }