aboutsummaryrefslogtreecommitdiffstats
path: root/lib/radix-tree.c
diff options
context:
space:
mode:
authorJohannes Weiner <hannes@cmpxchg.org>2014-04-03 17:47:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-03 19:21:00 -0400
commit53c59f262d747ea82e7414774c59a489501186a0 (patch)
tree7e7e6a3d2d418364bf071ee14061c77fab40cac7 /lib/radix-tree.c
parent55881bc76faf54653a1ba71770150f13fc85739c (diff)
lib: radix-tree: add radix_tree_delete_item()
Provide a function that does not just delete an entry at a given index, but also allows passing in an expected item. Delete only if that item is still located at the specified index. This is handy when lockless tree traversals want to delete entries as well because they don't have to do an second, locked lookup to verify the slot has not changed under them before deleting the entry. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Minchan Kim <minchan@kernel.org> Reviewed-by: Rik van Riel <riel@redhat.com> Acked-by: Mel Gorman <mgorman@suse.de> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Bob Liu <bob.liu@oracle.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Dave Chinner <david@fromorbit.com> Cc: Greg Thelen <gthelen@google.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Luigi Semenzato <semenzato@google.com> Cc: Metin Doslu <metin@citusdata.com> Cc: Michel Lespinasse <walken@google.com> Cc: Ozgun Erdogan <ozgun@citusdata.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Roman Gushchin <klamm@yandex-team.ru> Cc: Ryan Mallon <rmallon@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/radix-tree.c')
-rw-r--r--lib/radix-tree.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index bd4a8dfdf0b8..d832117e7d94 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -1337,15 +1337,18 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
1337} 1337}
1338 1338
1339/** 1339/**
1340 * radix_tree_delete - delete an item from a radix tree 1340 * radix_tree_delete_item - delete an item from a radix tree
1341 * @root: radix tree root 1341 * @root: radix tree root
1342 * @index: index key 1342 * @index: index key
1343 * @item: expected item
1343 * 1344 *
1344 * Remove the item at @index from the radix tree rooted at @root. 1345 * Remove @item at @index from the radix tree rooted at @root.
1345 * 1346 *
1346 * Returns the address of the deleted item, or NULL if it was not present. 1347 * Returns the address of the deleted item, or NULL if it was not present
1348 * or the entry at the given @index was not @item.
1347 */ 1349 */
1348void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) 1350void *radix_tree_delete_item(struct radix_tree_root *root,
1351 unsigned long index, void *item)
1349{ 1352{
1350 struct radix_tree_node *node = NULL; 1353 struct radix_tree_node *node = NULL;
1351 struct radix_tree_node *slot = NULL; 1354 struct radix_tree_node *slot = NULL;
@@ -1380,6 +1383,11 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
1380 if (slot == NULL) 1383 if (slot == NULL)
1381 goto out; 1384 goto out;
1382 1385
1386 if (item && slot != item) {
1387 slot = NULL;
1388 goto out;
1389 }
1390
1383 /* 1391 /*
1384 * Clear all tags associated with the item to be deleted. 1392 * Clear all tags associated with the item to be deleted.
1385 * This way of doing it would be inefficient, but seldom is any set. 1393 * This way of doing it would be inefficient, but seldom is any set.
@@ -1424,6 +1432,21 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
1424out: 1432out:
1425 return slot; 1433 return slot;
1426} 1434}
1435EXPORT_SYMBOL(radix_tree_delete_item);
1436
1437/**
1438 * radix_tree_delete - delete an item from a radix tree
1439 * @root: radix tree root
1440 * @index: index key
1441 *
1442 * Remove the item at @index from the radix tree rooted at @root.
1443 *
1444 * Returns the address of the deleted item, or NULL if it was not present.
1445 */
1446void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
1447{
1448 return radix_tree_delete_item(root, index, NULL);
1449}
1427EXPORT_SYMBOL(radix_tree_delete); 1450EXPORT_SYMBOL(radix_tree_delete);
1428 1451
1429/** 1452/**