mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
radix-tree: delete radix_tree_locate_item()
This rather complicated function can be better implemented as an iterator. It has only one caller, so move the functionality to the only place that needs it. Update the test suite to follow the same pattern. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox <[email protected]> Acked-by: Konstantin Khlebnikov <[email protected]> Tested-by: Kirill A. Shutemov <[email protected]> Cc: Ross Zwisler <[email protected]> Cc: Matthew Wilcox <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
148deab223
commit
478922e2b0
6 changed files with 53 additions and 105 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue