|
@@ -1579,105 +1579,6 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results,
|
|
|
}
|
|
|
EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot);
|
|
|
|
|
|
-#if defined(CONFIG_SHMEM) && defined(CONFIG_SWAP)
|
|
|
-#include <linux/sched.h> /* for cond_resched() */
|
|
|
-
|
|
|
-struct locate_info {
|
|
|
- unsigned long found_index;
|
|
|
- bool stop;
|
|
|
-};
|
|
|
-
|
|
|
-/*
|
|
|
- * This linear search is at present only useful to shmem_unuse_inode().
|
|
|
- */
|
|
|
-static unsigned long __locate(struct radix_tree_node *slot, void *item,
|
|
|
- unsigned long index, struct locate_info *info)
|
|
|
-{
|
|
|
- unsigned long i;
|
|
|
-
|
|
|
- do {
|
|
|
- unsigned int shift = slot->shift;
|
|
|
-
|
|
|
- for (i = (index >> shift) & RADIX_TREE_MAP_MASK;
|
|
|
- i < RADIX_TREE_MAP_SIZE;
|
|
|
- i++, index += (1UL << shift)) {
|
|
|
- struct radix_tree_node *node =
|
|
|
- rcu_dereference_raw(slot->slots[i]);
|
|
|
- if (node == RADIX_TREE_RETRY)
|
|
|
- goto out;
|
|
|
- if (!radix_tree_is_internal_node(node)) {
|
|
|
- if (node == item) {
|
|
|
- info->found_index = index;
|
|
|
- info->stop = true;
|
|
|
- goto out;
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
- node = entry_to_node(node);
|
|
|
- if (is_sibling_entry(slot, node))
|
|
|
- continue;
|
|
|
- slot = node;
|
|
|
- break;
|
|
|
- }
|
|
|
- } while (i < RADIX_TREE_MAP_SIZE);
|
|
|
-
|
|
|
-out:
|
|
|
- if ((index == 0) && (i == RADIX_TREE_MAP_SIZE))
|
|
|
- info->stop = true;
|
|
|
- return index;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * radix_tree_locate_item - search through radix tree for item
|
|
|
- * @root: radix tree root
|
|
|
- * @item: item to be found
|
|
|
- *
|
|
|
- * Returns index where item was found, or -1 if not found.
|
|
|
- * Caller must hold no lock (since this time-consuming function needs
|
|
|
- * to be preemptible), and must check afterwards if item is still there.
|
|
|
- */
|
|
|
-unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item)
|
|
|
-{
|
|
|
- struct radix_tree_node *node;
|
|
|
- unsigned long max_index;
|
|
|
- unsigned long cur_index = 0;
|
|
|
- struct locate_info info = {
|
|
|
- .found_index = -1,
|
|
|
- .stop = false,
|
|
|
- };
|
|
|
-
|
|
|
- do {
|
|
|
- rcu_read_lock();
|
|
|
- node = rcu_dereference_raw(root->rnode);
|
|
|
- if (!radix_tree_is_internal_node(node)) {
|
|
|
- rcu_read_unlock();
|
|
|
- if (node == item)
|
|
|
- info.found_index = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- node = entry_to_node(node);
|
|
|
-
|
|
|
- max_index = node_maxindex(node);
|
|
|
- if (cur_index > max_index) {
|
|
|
- rcu_read_unlock();
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- cur_index = __locate(node, item, cur_index, &info);
|
|
|
- rcu_read_unlock();
|
|
|
- cond_resched();
|
|
|
- } while (!info.stop && cur_index <= max_index);
|
|
|
-
|
|
|
- return info.found_index;
|
|
|
-}
|
|
|
-#else
|
|
|
-unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-#endif /* CONFIG_SHMEM && CONFIG_SWAP */
|
|
|
-
|
|
|
/**
|
|
|
* __radix_tree_delete_node - try to free node after clearing a slot
|
|
|
* @root: radix tree root
|