diff options
Diffstat (limited to 'lib/radix-tree.c')
| -rw-r--r-- | lib/radix-tree.c | 1111 | 
1 files changed, 590 insertions, 521 deletions
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 5086bb962b4..3291a8e3749 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -3,6 +3,7 @@   * Portions Copyright (C) 2001 Christoph Hellwig   * Copyright (C) 2005 SGI, Christoph Lameter   * Copyright (C) 2006 Nick Piggin + * Copyright (C) 2012 Konstantin Khlebnikov   *   * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License as @@ -22,46 +23,19 @@  #include <linux/errno.h>  #include <linux/init.h>  #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/export.h>  #include <linux/radix-tree.h>  #include <linux/percpu.h>  #include <linux/slab.h> +#include <linux/kmemleak.h>  #include <linux/notifier.h>  #include <linux/cpu.h>  #include <linux/string.h>  #include <linux/bitops.h>  #include <linux/rcupdate.h> +#include <linux/hardirq.h>		/* in_interrupt() */ -#ifdef __KERNEL__ -#define RADIX_TREE_MAP_SHIFT	(CONFIG_BASE_SMALL ? 4 : 6) -#else -#define RADIX_TREE_MAP_SHIFT	3	/* For more stressful testing */ -#endif - -#define RADIX_TREE_MAP_SIZE	(1UL << RADIX_TREE_MAP_SHIFT) -#define RADIX_TREE_MAP_MASK	(RADIX_TREE_MAP_SIZE-1) - -#define RADIX_TREE_TAG_LONGS	\ -	((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG) - -struct radix_tree_node { -	unsigned int	height;		/* Height from the bottom */ -	unsigned int	count; -	struct rcu_head	rcu_head; -	void __rcu	*slots[RADIX_TREE_MAP_SIZE]; -	unsigned long	tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; -}; - -struct radix_tree_path { -	struct radix_tree_node *node; -	int offset; -}; - -#define RADIX_TREE_INDEX_BITS  (8 /* CHAR_BIT */ * sizeof(unsigned long)) -#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \ -					  RADIX_TREE_MAP_SHIFT)) -  /*   * The height_to_maxindex array needs to be one deeper than the maximum   * path as height 0 holds only 1 entry. @@ -74,11 +48,24 @@ static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;  static struct kmem_cache *radix_tree_node_cachep;  /* + * The radix tree is variable-height, so an insert operation not only has + * to build the branch to its corresponding item, it also has to build the + * branch to existing items if the size has to be increased (by + * radix_tree_extend). + * + * The worst case is a zero height tree with just a single item at index 0, + * and then inserting an item at index ULONG_MAX. This requires 2 new branches + * of RADIX_TREE_MAX_PATH size to be created, with only the root node shared. + * Hence: + */ +#define RADIX_TREE_PRELOAD_SIZE (RADIX_TREE_MAX_PATH * 2 - 1) + +/*   * Per-cpu pool of preloaded nodes   */  struct radix_tree_preload {  	int nr; -	struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH]; +	struct radix_tree_node *nodes[RADIX_TREE_PRELOAD_SIZE];  };  static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; @@ -148,6 +135,43 @@ static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag)  	}  	return 0;  } + +/** + * radix_tree_find_next_bit - find the next set bit in a memory region + * + * @addr: The address to base the search on + * @size: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * Unrollable variant of find_next_bit() for constant size arrays. + * Tail bits starting from size to roundup(size, BITS_PER_LONG) must be zero. + * Returns next bit offset, or size if nothing found. + */ +static __always_inline unsigned long +radix_tree_find_next_bit(const unsigned long *addr, +			 unsigned long size, unsigned long offset) +{ +	if (!__builtin_constant_p(size)) +		return find_next_bit(addr, size, offset); + +	if (offset < size) { +		unsigned long tmp; + +		addr += offset / BITS_PER_LONG; +		tmp = *addr >> (offset % BITS_PER_LONG); +		if (tmp) +			return __ffs(tmp) + offset; +		offset = (offset + BITS_PER_LONG) & ~(BITS_PER_LONG - 1); +		while (offset < size) { +			tmp = *++addr; +			if (tmp) +				return __ffs(tmp) + offset; +			offset += BITS_PER_LONG; +		} +	} +	return size; +} +  /*   * This assumes that the caller has performed appropriate preallocation, and   * that the caller has pinned this thread of control to the current CPU. @@ -158,7 +182,12 @@ radix_tree_node_alloc(struct radix_tree_root *root)  	struct radix_tree_node *ret = NULL;  	gfp_t gfp_mask = root_gfp_mask(root); -	if (!(gfp_mask & __GFP_WAIT)) { +	/* +	 * Preload code isn't irq safe and it doesn't make sence to use +	 * preloading in the interrupt anyway as all the allocations have to +	 * be atomic. So just do normal allocation when in interrupt. +	 */ +	if (!(gfp_mask & __GFP_WAIT) && !in_interrupt()) {  		struct radix_tree_preload *rtp;  		/* @@ -166,12 +195,17 @@ radix_tree_node_alloc(struct radix_tree_root *root)  		 * succeed in getting a node here (and never reach  		 * kmem_cache_alloc)  		 */ -		rtp = &__get_cpu_var(radix_tree_preloads); +		rtp = this_cpu_ptr(&radix_tree_preloads);  		if (rtp->nr) {  			ret = rtp->nodes[rtp->nr - 1];  			rtp->nodes[rtp->nr - 1] = NULL;  			rtp->nr--;  		} +		/* +		 * Update the allocation stack trace as this is more useful +		 * for debugging. +		 */ +		kmemleak_update_trace(ret);  	}  	if (ret == NULL)  		ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask); @@ -215,21 +249,21 @@ radix_tree_node_free(struct radix_tree_node *node)   * To make use of this facility, the radix tree must be initialised without   * __GFP_WAIT being passed to INIT_RADIX_TREE().   */ -int radix_tree_preload(gfp_t gfp_mask) +static int __radix_tree_preload(gfp_t gfp_mask)  {  	struct radix_tree_preload *rtp;  	struct radix_tree_node *node;  	int ret = -ENOMEM;  	preempt_disable(); -	rtp = &__get_cpu_var(radix_tree_preloads); +	rtp = this_cpu_ptr(&radix_tree_preloads);  	while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {  		preempt_enable();  		node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);  		if (node == NULL)  			goto out;  		preempt_disable(); -		rtp = &__get_cpu_var(radix_tree_preloads); +		rtp = this_cpu_ptr(&radix_tree_preloads);  		if (rtp->nr < ARRAY_SIZE(rtp->nodes))  			rtp->nodes[rtp->nr++] = node;  		else @@ -239,9 +273,40 @@ int radix_tree_preload(gfp_t gfp_mask)  out:  	return ret;  } + +/* + * Load up this CPU's radix_tree_node buffer with sufficient objects to + * ensure that the addition of a single element in the tree cannot fail.  On + * success, return zero, with preemption disabled.  On error, return -ENOMEM + * with preemption not disabled. + * + * To make use of this facility, the radix tree must be initialised without + * __GFP_WAIT being passed to INIT_RADIX_TREE(). + */ +int radix_tree_preload(gfp_t gfp_mask) +{ +	/* Warn on non-sensical use... */ +	WARN_ON_ONCE(!(gfp_mask & __GFP_WAIT)); +	return __radix_tree_preload(gfp_mask); +}  EXPORT_SYMBOL(radix_tree_preload);  /* + * The same as above function, except we don't guarantee preloading happens. + * We do it, if we decide it helps. On success, return zero with preemption + * disabled. On error, return -ENOMEM with preemption not disabled. + */ +int radix_tree_maybe_preload(gfp_t gfp_mask) +{ +	if (gfp_mask & __GFP_WAIT) +		return __radix_tree_preload(gfp_mask); +	/* Preloading doesn't help anything with this gfp mask, skip it */ +	preempt_disable(); +	return 0; +} +EXPORT_SYMBOL(radix_tree_maybe_preload); + +/*   *	Return the maximum key which can be store into a   *	radix tree with height HEIGHT.   */ @@ -256,6 +321,7 @@ static inline unsigned long radix_tree_maxindex(unsigned int height)  static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)  {  	struct radix_tree_node *node; +	struct radix_tree_node *slot;  	unsigned int height;  	int tag; @@ -274,18 +340,24 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)  		if (!(node = radix_tree_node_alloc(root)))  			return -ENOMEM; -		/* Increase the height.  */ -		node->slots[0] = indirect_to_ptr(root->rnode); -  		/* Propagate the aggregated tag info into the new root */  		for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {  			if (root_tag_get(root, tag))  				tag_set(node, tag, 0);  		} +		/* Increase the height.  */  		newheight = root->height+1; -		node->height = newheight; +		BUG_ON(newheight & ~RADIX_TREE_HEIGHT_MASK); +		node->path = newheight;  		node->count = 1; +		node->parent = NULL; +		slot = root->rnode; +		if (newheight > 1) { +			slot = indirect_to_ptr(slot); +			slot->parent = node; +		} +		node->slots[0] = slot;  		node = ptr_to_indirect(node);  		rcu_assign_pointer(root->rnode, node);  		root->height = newheight; @@ -295,23 +367,28 @@ out:  }  /** - *	radix_tree_insert    -    insert into a radix tree + *	__radix_tree_create	-	create a slot in a radix tree   *	@root:		radix tree root   *	@index:		index key - *	@item:		item to insert + *	@nodep:		returns node + *	@slotp:		returns slot   * - *	Insert an item into the radix tree at position @index. + *	Create, if necessary, and return the node and slot for an item + *	at position @index in the radix tree @root. + * + *	Until there is more than one item in the tree, no nodes are + *	allocated and @root->rnode is used as a direct slot instead of + *	pointing to a node, in which case *@nodep will be NULL. + * + *	Returns -ENOMEM, or 0 for success.   */ -int radix_tree_insert(struct radix_tree_root *root, -			unsigned long index, void *item) +int __radix_tree_create(struct radix_tree_root *root, unsigned long index, +			struct radix_tree_node **nodep, void ***slotp)  {  	struct radix_tree_node *node = NULL, *slot; -	unsigned int height, shift; -	int offset; +	unsigned int height, shift, offset;  	int error; -	BUG_ON(radix_tree_is_indirect_ptr(item)); -  	/* Make sure the tree is high enough.  */  	if (index > radix_tree_maxindex(root->height)) {  		error = radix_tree_extend(root, index); @@ -330,10 +407,12 @@ int radix_tree_insert(struct radix_tree_root *root,  			/* Have to add a child node.  */  			if (!(slot = radix_tree_node_alloc(root)))  				return -ENOMEM; -			slot->height = height; +			slot->path = height; +			slot->parent = node;  			if (node) {  				rcu_assign_pointer(node->slots[offset], slot);  				node->count++; +				slot->path |= offset << RADIX_TREE_HEIGHT_SHIFT;  			} else  				rcu_assign_pointer(root->rnode, ptr_to_indirect(slot));  		} @@ -346,16 +425,42 @@ int radix_tree_insert(struct radix_tree_root *root,  		height--;  	} -	if (slot != NULL) +	if (nodep) +		*nodep = node; +	if (slotp) +		*slotp = node ? node->slots + offset : (void **)&root->rnode; +	return 0; +} + +/** + *	radix_tree_insert    -    insert into a radix tree + *	@root:		radix tree root + *	@index:		index key + *	@item:		item to insert + * + *	Insert an item into the radix tree at position @index. + */ +int radix_tree_insert(struct radix_tree_root *root, +			unsigned long index, void *item) +{ +	struct radix_tree_node *node; +	void **slot; +	int error; + +	BUG_ON(radix_tree_is_indirect_ptr(item)); + +	error = __radix_tree_create(root, index, &node, &slot); +	if (error) +		return error; +	if (*slot != NULL)  		return -EEXIST; +	rcu_assign_pointer(*slot, item);  	if (node) {  		node->count++; -		rcu_assign_pointer(node->slots[offset], item); -		BUG_ON(tag_get(node, 0, offset)); -		BUG_ON(tag_get(node, 1, offset)); +		BUG_ON(tag_get(node, 0, index & RADIX_TREE_MAP_MASK)); +		BUG_ON(tag_get(node, 1, index & RADIX_TREE_MAP_MASK));  	} else { -		rcu_assign_pointer(root->rnode, item);  		BUG_ON(root_tag_get(root, 0));  		BUG_ON(root_tag_get(root, 1));  	} @@ -364,15 +469,26 @@ int radix_tree_insert(struct radix_tree_root *root,  }  EXPORT_SYMBOL(radix_tree_insert); -/* - * is_slot == 1 : search for the slot. - * is_slot == 0 : search for the node. +/** + *	__radix_tree_lookup	-	lookup an item in a radix tree + *	@root:		radix tree root + *	@index:		index key + *	@nodep:		returns node + *	@slotp:		returns slot + * + *	Lookup and return the item at position @index in the radix + *	tree @root. + * + *	Until there is more than one item in the tree, no nodes are + *	allocated and @root->rnode is used as a direct slot instead of + *	pointing to a node, in which case *@nodep will be NULL.   */ -static void *radix_tree_lookup_element(struct radix_tree_root *root, -				unsigned long index, int is_slot) +void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index, +			  struct radix_tree_node **nodep, void ***slotp)  { +	struct radix_tree_node *node, *parent;  	unsigned int height, shift; -	struct radix_tree_node *node, **slot; +	void **slot;  	node = rcu_dereference_raw(root->rnode);  	if (node == NULL) @@ -381,19 +497,24 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root,  	if (!radix_tree_is_indirect_ptr(node)) {  		if (index > 0)  			return NULL; -		return is_slot ? (void *)&root->rnode : node; + +		if (nodep) +			*nodep = NULL; +		if (slotp) +			*slotp = (void **)&root->rnode; +		return node;  	}  	node = indirect_to_ptr(node); -	height = node->height; +	height = node->path & RADIX_TREE_HEIGHT_MASK;  	if (index > radix_tree_maxindex(height))  		return NULL;  	shift = (height-1) * RADIX_TREE_MAP_SHIFT;  	do { -		slot = (struct radix_tree_node **) -			(node->slots + ((index>>shift) & RADIX_TREE_MAP_MASK)); +		parent = node; +		slot = node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK);  		node = rcu_dereference_raw(*slot);  		if (node == NULL)  			return NULL; @@ -402,7 +523,11 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root,  		height--;  	} while (height > 0); -	return is_slot ? (void *)slot : indirect_to_ptr(node); +	if (nodep) +		*nodep = parent; +	if (slotp) +		*slotp = slot; +	return node;  }  /** @@ -420,7 +545,11 @@ static void *radix_tree_lookup_element(struct radix_tree_root *root,   */  void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)  { -	return (void **)radix_tree_lookup_element(root, index, 1); +	void **slot; + +	if (!__radix_tree_lookup(root, index, NULL, &slot)) +		return NULL; +	return slot;  }  EXPORT_SYMBOL(radix_tree_lookup_slot); @@ -438,7 +567,7 @@ EXPORT_SYMBOL(radix_tree_lookup_slot);   */  void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)  { -	return radix_tree_lookup_element(root, index, 0); +	return __radix_tree_lookup(root, index, NULL, NULL);  }  EXPORT_SYMBOL(radix_tree_lookup); @@ -504,47 +633,41 @@ EXPORT_SYMBOL(radix_tree_tag_set);  void *radix_tree_tag_clear(struct radix_tree_root *root,  			unsigned long index, unsigned int tag)  { -	/* -	 * The radix tree path needs to be one longer than the maximum path -	 * since the "list" is null terminated. -	 */ -	struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; +	struct radix_tree_node *node = NULL;  	struct radix_tree_node *slot = NULL;  	unsigned int height, shift; +	int uninitialized_var(offset);  	height = root->height;  	if (index > radix_tree_maxindex(height))  		goto out; -	shift = (height - 1) * RADIX_TREE_MAP_SHIFT; -	pathp->node = NULL; +	shift = height * RADIX_TREE_MAP_SHIFT;  	slot = indirect_to_ptr(root->rnode); -	while (height > 0) { -		int offset; - +	while (shift) {  		if (slot == NULL)  			goto out; +		shift -= RADIX_TREE_MAP_SHIFT;  		offset = (index >> shift) & RADIX_TREE_MAP_MASK; -		pathp[1].offset = offset; -		pathp[1].node = slot; +		node = slot;  		slot = slot->slots[offset]; -		pathp++; -		shift -= RADIX_TREE_MAP_SHIFT; -		height--;  	}  	if (slot == NULL)  		goto out; -	while (pathp->node) { -		if (!tag_get(pathp->node, tag, pathp->offset)) +	while (node) { +		if (!tag_get(node, tag, offset))  			goto out; -		tag_clear(pathp->node, tag, pathp->offset); -		if (any_tag_set(pathp->node, tag)) +		tag_clear(node, tag, offset); +		if (any_tag_set(node, tag))  			goto out; -		pathp--; + +		index >>= RADIX_TREE_MAP_SHIFT; +		offset = index & RADIX_TREE_MAP_MASK; +		node = node->parent;  	}  	/* clear the root's tag bit */ @@ -576,7 +699,6 @@ int radix_tree_tag_get(struct radix_tree_root *root,  {  	unsigned int height, shift;  	struct radix_tree_node *node; -	int saw_unset_tag = 0;  	/* check the root's tag bit */  	if (!root_tag_get(root, tag)) @@ -590,7 +712,7 @@ int radix_tree_tag_get(struct radix_tree_root *root,  		return (index == 0);  	node = indirect_to_ptr(node); -	height = node->height; +	height = node->path & RADIX_TREE_HEIGHT_MASK;  	if (index > radix_tree_maxindex(height))  		return 0; @@ -603,15 +725,10 @@ int radix_tree_tag_get(struct radix_tree_root *root,  			return 0;  		offset = (index >> shift) & RADIX_TREE_MAP_MASK; - -		/* -		 * This is just a debug check.  Later, we can bale as soon as -		 * we see an unset tag. -		 */  		if (!tag_get(node, tag, offset)) -			saw_unset_tag = 1; +			return 0;  		if (height == 1) -			return !!tag_get(node, tag, offset); +			return 1;  		node = rcu_dereference_raw(node->slots[offset]);  		shift -= RADIX_TREE_MAP_SHIFT;  		height--; @@ -620,6 +737,123 @@ int radix_tree_tag_get(struct radix_tree_root *root,  EXPORT_SYMBOL(radix_tree_tag_get);  /** + * radix_tree_next_chunk - find next chunk of slots for iteration + * + * @root:	radix tree root + * @iter:	iterator state + * @flags:	RADIX_TREE_ITER_* flags and tag index + * Returns:	pointer to chunk first slot, or NULL if iteration is over + */ +void **radix_tree_next_chunk(struct radix_tree_root *root, +			     struct radix_tree_iter *iter, unsigned flags) +{ +	unsigned shift, tag = flags & RADIX_TREE_ITER_TAG_MASK; +	struct radix_tree_node *rnode, *node; +	unsigned long index, offset, height; + +	if ((flags & RADIX_TREE_ITER_TAGGED) && !root_tag_get(root, tag)) +		return NULL; + +	/* +	 * Catch next_index overflow after ~0UL. iter->index never overflows +	 * during iterating; it can be zero only at the beginning. +	 * And we cannot overflow iter->next_index in a single step, +	 * because RADIX_TREE_MAP_SHIFT < BITS_PER_LONG. +	 * +	 * This condition also used by radix_tree_next_slot() to stop +	 * contiguous iterating, and forbid swithing to the next chunk. +	 */ +	index = iter->next_index; +	if (!index && iter->index) +		return NULL; + +	rnode = rcu_dereference_raw(root->rnode); +	if (radix_tree_is_indirect_ptr(rnode)) { +		rnode = indirect_to_ptr(rnode); +	} else if (rnode && !index) { +		/* Single-slot tree */ +		iter->index = 0; +		iter->next_index = 1; +		iter->tags = 1; +		return (void **)&root->rnode; +	} else +		return NULL; + +restart: +	height = rnode->path & RADIX_TREE_HEIGHT_MASK; +	shift = (height - 1) * RADIX_TREE_MAP_SHIFT; +	offset = index >> shift; + +	/* Index outside of the tree */ +	if (offset >= RADIX_TREE_MAP_SIZE) +		return NULL; + +	node = rnode; +	while (1) { +		if ((flags & RADIX_TREE_ITER_TAGGED) ? +				!test_bit(offset, node->tags[tag]) : +				!node->slots[offset]) { +			/* Hole detected */ +			if (flags & RADIX_TREE_ITER_CONTIG) +				return NULL; + +			if (flags & RADIX_TREE_ITER_TAGGED) +				offset = radix_tree_find_next_bit( +						node->tags[tag], +						RADIX_TREE_MAP_SIZE, +						offset + 1); +			else +				while (++offset	< RADIX_TREE_MAP_SIZE) { +					if (node->slots[offset]) +						break; +				} +			index &= ~((RADIX_TREE_MAP_SIZE << shift) - 1); +			index += offset << shift; +			/* Overflow after ~0UL */ +			if (!index) +				return NULL; +			if (offset == RADIX_TREE_MAP_SIZE) +				goto restart; +		} + +		/* This is leaf-node */ +		if (!shift) +			break; + +		node = rcu_dereference_raw(node->slots[offset]); +		if (node == NULL) +			goto restart; +		shift -= RADIX_TREE_MAP_SHIFT; +		offset = (index >> shift) & RADIX_TREE_MAP_MASK; +	} + +	/* Update the iterator state */ +	iter->index = index; +	iter->next_index = (index | RADIX_TREE_MAP_MASK) + 1; + +	/* Construct iter->tags bit-mask from node->tags[tag] array */ +	if (flags & RADIX_TREE_ITER_TAGGED) { +		unsigned tag_long, tag_bit; + +		tag_long = offset / BITS_PER_LONG; +		tag_bit  = offset % BITS_PER_LONG; +		iter->tags = node->tags[tag][tag_long] >> tag_bit; +		/* This never happens if RADIX_TREE_TAG_LONGS == 1 */ +		if (tag_long < RADIX_TREE_TAG_LONGS - 1) { +			/* Pick tags from next element */ +			if (tag_bit) +				iter->tags |= node->tags[tag][tag_long + 1] << +						(BITS_PER_LONG - tag_bit); +			/* Clip chunk size, here only BITS_PER_LONG tags */ +			iter->next_index = index + BITS_PER_LONG; +		} +	} + +	return node->slots + offset; +} +EXPORT_SYMBOL(radix_tree_next_chunk); + +/**   * radix_tree_range_tag_if_tagged - for each item in given range set given   *				   tag if item has another tag set   * @root:		radix tree root @@ -652,8 +886,7 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,  		unsigned int iftag, unsigned int settag)  {  	unsigned int height = root->height; -	struct radix_tree_path path[height]; -	struct radix_tree_path *pathp = path; +	struct radix_tree_node *node = NULL;  	struct radix_tree_node *slot;  	unsigned int shift;  	unsigned long tagged = 0; @@ -677,14 +910,8 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,  	shift = (height - 1) * RADIX_TREE_MAP_SHIFT;  	slot = indirect_to_ptr(root->rnode); -	/* -	 * we fill the path from (root->height - 2) to 0, leaving the index at -	 * (root->height - 1) as a terminator. Zero the node in the terminator -	 * so that we can use this to end walk loops back up the path. -	 */ -	path[height - 1].node = NULL; -  	for (;;) { +		unsigned long upindex;  		int offset;  		offset = (index >> shift) & RADIX_TREE_MAP_MASK; @@ -692,12 +919,10 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,  			goto next;  		if (!tag_get(slot, iftag, offset))  			goto next; -		if (height > 1) { +		if (shift) {  			/* Go down one level */ -			height--;  			shift -= RADIX_TREE_MAP_SHIFT; -			path[height - 1].node = slot; -			path[height - 1].offset = offset; +			node = slot;  			slot = slot->slots[offset];  			continue;  		} @@ -707,15 +932,27 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,  		tag_set(slot, settag, offset);  		/* walk back up the path tagging interior nodes */ -		pathp = &path[0]; -		while (pathp->node) { +		upindex = index; +		while (node) { +			upindex >>= RADIX_TREE_MAP_SHIFT; +			offset = upindex & RADIX_TREE_MAP_MASK; +  			/* stop if we find a node with the tag already set */ -			if (tag_get(pathp->node, settag, pathp->offset)) +			if (tag_get(node, settag, offset))  				break; -			tag_set(pathp->node, settag, pathp->offset); -			pathp++; +			tag_set(node, settag, offset); +			node = node->parent;  		} +		/* +		 * Small optimization: now clear that node pointer. +		 * Since all of this slot's ancestors now have the tag set +		 * from setting it above, we have no further need to walk +		 * back up the tree setting tags, until we update slot to +		 * point to another radix_tree_node. +		 */ +		node = NULL; +  next:  		/* Go to next item at level determined by 'shift' */  		index = ((index >> shift) + 1) << shift; @@ -730,144 +967,22 @@ next:  			 * last_index is guaranteed to be in the tree, what  			 * we do below cannot wander astray.  			 */ -			slot = path[height - 1].node; -			height++; +			slot = slot->parent;  			shift += RADIX_TREE_MAP_SHIFT;  		}  	}  	/* -	 * The iftag must have been set somewhere because otherwise -	 * we would return immediated at the beginning of the function +	 * We need not to tag the root tag if there is no tag which is set with +	 * settag within the range from *first_indexp to last_index.  	 */ -	root_tag_set(root, settag); +	if (tagged > 0) +		root_tag_set(root, settag);  	*first_indexp = index;  	return tagged;  }  EXPORT_SYMBOL(radix_tree_range_tag_if_tagged); - -/** - *	radix_tree_next_hole    -    find the next hole (not-present entry) - *	@root:		tree root - *	@index:		index key - *	@max_scan:	maximum range to search - * - *	Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the lowest - *	indexed hole. - * - *	Returns: the index of the hole if found, otherwise returns an index - *	outside of the set specified (in which case 'return - index >= max_scan' - *	will be true). In rare cases of index wrap-around, 0 will be returned. - * - *	radix_tree_next_hole may be called under rcu_read_lock. However, like - *	radix_tree_gang_lookup, this will not atomically search a snapshot of - *	the tree at a single point in time. For example, if a hole is created - *	at index 5, then subsequently a hole is created at index 10, - *	radix_tree_next_hole covering both indexes may return 10 if called - *	under rcu_read_lock. - */ -unsigned long radix_tree_next_hole(struct radix_tree_root *root, -				unsigned long index, unsigned long max_scan) -{ -	unsigned long i; - -	for (i = 0; i < max_scan; i++) { -		if (!radix_tree_lookup(root, index)) -			break; -		index++; -		if (index == 0) -			break; -	} - -	return index; -} -EXPORT_SYMBOL(radix_tree_next_hole); - -/** - *	radix_tree_prev_hole    -    find the prev hole (not-present entry) - *	@root:		tree root - *	@index:		index key - *	@max_scan:	maximum range to search - * - *	Search backwards in the range [max(index-max_scan+1, 0), index] - *	for the first hole. - * - *	Returns: the index of the hole if found, otherwise returns an index - *	outside of the set specified (in which case 'index - return >= max_scan' - *	will be true). In rare cases of wrap-around, ULONG_MAX will be returned. - * - *	radix_tree_next_hole may be called under rcu_read_lock. However, like - *	radix_tree_gang_lookup, this will not atomically search a snapshot of - *	the tree at a single point in time. For example, if a hole is created - *	at index 10, then subsequently a hole is created at index 5, - *	radix_tree_prev_hole covering both indexes may return 5 if called under - *	rcu_read_lock. - */ -unsigned long radix_tree_prev_hole(struct radix_tree_root *root, -				   unsigned long index, unsigned long max_scan) -{ -	unsigned long i; - -	for (i = 0; i < max_scan; i++) { -		if (!radix_tree_lookup(root, index)) -			break; -		index--; -		if (index == ULONG_MAX) -			break; -	} - -	return index; -} -EXPORT_SYMBOL(radix_tree_prev_hole); - -static unsigned int -__lookup(struct radix_tree_node *slot, void ***results, unsigned long index, -	unsigned int max_items, unsigned long *next_index) -{ -	unsigned int nr_found = 0; -	unsigned int shift, height; -	unsigned long i; - -	height = slot->height; -	if (height == 0) -		goto out; -	shift = (height-1) * RADIX_TREE_MAP_SHIFT; - -	for ( ; height > 1; height--) { -		i = (index >> shift) & RADIX_TREE_MAP_MASK; -		for (;;) { -			if (slot->slots[i] != NULL) -				break; -			index &= ~((1UL << shift) - 1); -			index += 1UL << shift; -			if (index == 0) -				goto out;	/* 32-bit wraparound */ -			i++; -			if (i == RADIX_TREE_MAP_SIZE) -				goto out; -		} - -		shift -= RADIX_TREE_MAP_SHIFT; -		slot = rcu_dereference_raw(slot->slots[i]); -		if (slot == NULL) -			goto out; -	} - -	/* Bottom level: grab some items */ -	for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { -		index++; -		if (slot->slots[i]) { -			results[nr_found++] = &(slot->slots[i]); -			if (nr_found == max_items) -				goto out; -		} -	} -out: -	*next_index = index; -	return nr_found; -} -  /**   *	radix_tree_gang_lookup - perform multiple lookup on a radix tree   *	@root:		radix tree root @@ -891,48 +1006,19 @@ unsigned int  radix_tree_gang_lookup(struct radix_tree_root *root, void **results,  			unsigned long first_index, unsigned int max_items)  { -	unsigned long max_index; -	struct radix_tree_node *node; -	unsigned long cur_index = first_index; -	unsigned int ret; +	struct radix_tree_iter iter; +	void **slot; +	unsigned int ret = 0; -	node = rcu_dereference_raw(root->rnode); -	if (!node) +	if (unlikely(!max_items))  		return 0; -	if (!radix_tree_is_indirect_ptr(node)) { -		if (first_index > 0) -			return 0; -		results[0] = node; -		return 1; -	} -	node = indirect_to_ptr(node); - -	max_index = radix_tree_maxindex(node->height); - -	ret = 0; -	while (ret < max_items) { -		unsigned int nr_found, slots_found, i; -		unsigned long next_index;	/* Index of next search */ - -		if (cur_index > max_index) -			break; -		slots_found = __lookup(node, (void ***)results + ret, cur_index, -					max_items - ret, &next_index); -		nr_found = 0; -		for (i = 0; i < slots_found; i++) { -			struct radix_tree_node *slot; -			slot = *(((void ***)results)[ret + i]); -			if (!slot) -				continue; -			results[ret + nr_found] = -				indirect_to_ptr(rcu_dereference_raw(slot)); -			nr_found++; -		} -		ret += nr_found; -		if (next_index == 0) +	radix_tree_for_each_slot(slot, root, &iter, first_index) { +		results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); +		if (!results[ret]) +			continue; +		if (++ret == max_items)  			break; -		cur_index = next_index;  	}  	return ret; @@ -943,6 +1029,7 @@ EXPORT_SYMBOL(radix_tree_gang_lookup);   *	radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree   *	@root:		radix tree root   *	@results:	where the results of the lookup are placed + *	@indices:	where their indices should be placed (but usually NULL)   *	@first_index:	start the lookup from this key   *	@max_items:	place up to this many items at *results   * @@ -957,112 +1044,29 @@ EXPORT_SYMBOL(radix_tree_gang_lookup);   *	protection, radix_tree_deref_slot may fail requiring a retry.   */  unsigned int -radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, +radix_tree_gang_lookup_slot(struct radix_tree_root *root, +			void ***results, unsigned long *indices,  			unsigned long first_index, unsigned int max_items)  { -	unsigned long max_index; -	struct radix_tree_node *node; -	unsigned long cur_index = first_index; -	unsigned int ret; +	struct radix_tree_iter iter; +	void **slot; +	unsigned int ret = 0; -	node = rcu_dereference_raw(root->rnode); -	if (!node) +	if (unlikely(!max_items))  		return 0; -	if (!radix_tree_is_indirect_ptr(node)) { -		if (first_index > 0) -			return 0; -		results[0] = (void **)&root->rnode; -		return 1; -	} -	node = indirect_to_ptr(node); - -	max_index = radix_tree_maxindex(node->height); - -	ret = 0; -	while (ret < max_items) { -		unsigned int slots_found; -		unsigned long next_index;	/* Index of next search */ - -		if (cur_index > max_index) -			break; -		slots_found = __lookup(node, results + ret, cur_index, -					max_items - ret, &next_index); -		ret += slots_found; -		if (next_index == 0) +	radix_tree_for_each_slot(slot, root, &iter, first_index) { +		results[ret] = slot; +		if (indices) +			indices[ret] = iter.index; +		if (++ret == max_items)  			break; -		cur_index = next_index;  	}  	return ret;  }  EXPORT_SYMBOL(radix_tree_gang_lookup_slot); -/* - * FIXME: the two tag_get()s here should use find_next_bit() instead of - * open-coding the search. - */ -static unsigned int -__lookup_tag(struct radix_tree_node *slot, void ***results, unsigned long index, -	unsigned int max_items, unsigned long *next_index, unsigned int tag) -{ -	unsigned int nr_found = 0; -	unsigned int shift, height; - -	height = slot->height; -	if (height == 0) -		goto out; -	shift = (height-1) * RADIX_TREE_MAP_SHIFT; - -	while (height > 0) { -		unsigned long i = (index >> shift) & RADIX_TREE_MAP_MASK ; - -		for (;;) { -			if (tag_get(slot, tag, i)) -				break; -			index &= ~((1UL << shift) - 1); -			index += 1UL << shift; -			if (index == 0) -				goto out;	/* 32-bit wraparound */ -			i++; -			if (i == RADIX_TREE_MAP_SIZE) -				goto out; -		} -		height--; -		if (height == 0) {	/* Bottom level: grab some items */ -			unsigned long j = index & RADIX_TREE_MAP_MASK; - -			for ( ; j < RADIX_TREE_MAP_SIZE; j++) { -				index++; -				if (!tag_get(slot, tag, j)) -					continue; -				/* -				 * Even though the tag was found set, we need to -				 * recheck that we have a non-NULL node, because -				 * if this lookup is lockless, it may have been -				 * subsequently deleted. -				 * -				 * Similar care must be taken in any place that -				 * lookup ->slots[x] without a lock (ie. can't -				 * rely on its value remaining the same). -				 */ -				if (slot->slots[j]) { -					results[nr_found++] = &(slot->slots[j]); -					if (nr_found == max_items) -						goto out; -				} -			} -		} -		shift -= RADIX_TREE_MAP_SHIFT; -		slot = rcu_dereference_raw(slot->slots[i]); -		if (slot == NULL) -			break; -	} -out: -	*next_index = index; -	return nr_found; -} -  /**   *	radix_tree_gang_lookup_tag - perform multiple lookup on a radix tree   *	                             based on a tag @@ -1081,52 +1085,19 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,  		unsigned long first_index, unsigned int max_items,  		unsigned int tag)  { -	struct radix_tree_node *node; -	unsigned long max_index; -	unsigned long cur_index = first_index; -	unsigned int ret; - -	/* check the root's tag bit */ -	if (!root_tag_get(root, tag)) -		return 0; +	struct radix_tree_iter iter; +	void **slot; +	unsigned int ret = 0; -	node = rcu_dereference_raw(root->rnode); -	if (!node) +	if (unlikely(!max_items))  		return 0; -	if (!radix_tree_is_indirect_ptr(node)) { -		if (first_index > 0) -			return 0; -		results[0] = node; -		return 1; -	} -	node = indirect_to_ptr(node); - -	max_index = radix_tree_maxindex(node->height); - -	ret = 0; -	while (ret < max_items) { -		unsigned int nr_found, slots_found, i; -		unsigned long next_index;	/* Index of next search */ - -		if (cur_index > max_index) -			break; -		slots_found = __lookup_tag(node, (void ***)results + ret, -				cur_index, max_items - ret, &next_index, tag); -		nr_found = 0; -		for (i = 0; i < slots_found; i++) { -			struct radix_tree_node *slot; -			slot = *(((void ***)results)[ret + i]); -			if (!slot) -				continue; -			results[ret + nr_found] = -				indirect_to_ptr(rcu_dereference_raw(slot)); -			nr_found++; -		} -		ret += nr_found; -		if (next_index == 0) +	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) { +		results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot)); +		if (!results[ret]) +			continue; +		if (++ret == max_items)  			break; -		cur_index = next_index;  	}  	return ret; @@ -1151,48 +1122,118 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results,  		unsigned long first_index, unsigned int max_items,  		unsigned int tag)  { -	struct radix_tree_node *node; -	unsigned long max_index; -	unsigned long cur_index = first_index; -	unsigned int ret; +	struct radix_tree_iter iter; +	void **slot; +	unsigned int ret = 0; -	/* check the root's tag bit */ -	if (!root_tag_get(root, tag)) +	if (unlikely(!max_items))  		return 0; -	node = rcu_dereference_raw(root->rnode); -	if (!node) -		return 0; +	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) { +		results[ret] = slot; +		if (++ret == max_items) +			break; +	} -	if (!radix_tree_is_indirect_ptr(node)) { -		if (first_index > 0) -			return 0; -		results[0] = (void **)&root->rnode; -		return 1; +	return ret; +} +EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); + +#if defined(CONFIG_SHMEM) && defined(CONFIG_SWAP) +#include <linux/sched.h> /* for cond_resched() */ + +/* + * 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, unsigned long *found_index) +{ +	unsigned int shift, height; +	unsigned long i; + +	height = slot->path & RADIX_TREE_HEIGHT_MASK; +	shift = (height-1) * RADIX_TREE_MAP_SHIFT; + +	for ( ; height > 1; height--) { +		i = (index >> shift) & RADIX_TREE_MAP_MASK; +		for (;;) { +			if (slot->slots[i] != NULL) +				break; +			index &= ~((1UL << shift) - 1); +			index += 1UL << shift; +			if (index == 0) +				goto out;	/* 32-bit wraparound */ +			i++; +			if (i == RADIX_TREE_MAP_SIZE) +				goto out; +		} + +		shift -= RADIX_TREE_MAP_SHIFT; +		slot = rcu_dereference_raw(slot->slots[i]); +		if (slot == NULL) +			goto out;  	} -	node = indirect_to_ptr(node); -	max_index = radix_tree_maxindex(node->height); +	/* Bottom level: check items */ +	for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { +		if (slot->slots[i] == item) { +			*found_index = index + i; +			index = 0; +			goto out; +		} +	} +	index += RADIX_TREE_MAP_SIZE; +out: +	return index; +} -	ret = 0; -	while (ret < max_items) { -		unsigned int slots_found; -		unsigned long next_index;	/* Index of next search */ +/** + *	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; +	unsigned long found_index = -1; -		if (cur_index > max_index) +	do { +		rcu_read_lock(); +		node = rcu_dereference_raw(root->rnode); +		if (!radix_tree_is_indirect_ptr(node)) { +			rcu_read_unlock(); +			if (node == item) +				found_index = 0;  			break; -		slots_found = __lookup_tag(node, results + ret, -				cur_index, max_items - ret, &next_index, tag); -		ret += slots_found; -		if (next_index == 0) +		} + +		node = indirect_to_ptr(node); +		max_index = radix_tree_maxindex(node->path & +						RADIX_TREE_HEIGHT_MASK); +		if (cur_index > max_index) { +			rcu_read_unlock();  			break; -		cur_index = next_index; -	} +		} -	return ret; -} -EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); +		cur_index = __locate(node, item, cur_index, &found_index); +		rcu_read_unlock(); +		cond_resched(); +	} while (cur_index != 0 && cur_index <= max_index); +	return 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_shrink    -    shrink height of a radix tree to minimal @@ -1203,7 +1244,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)  	/* try to shrink tree height */  	while (root->height > 0) {  		struct radix_tree_node *to_free = root->rnode; -		void *newptr; +		struct radix_tree_node *slot;  		BUG_ON(!radix_tree_is_indirect_ptr(to_free));  		to_free = indirect_to_ptr(to_free); @@ -1224,10 +1265,12 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)  		 * (to_free->slots[0]), it will be safe to dereference the new  		 * one (root->rnode) as far as dependent read barriers go.  		 */ -		newptr = to_free->slots[0]; -		if (root->height > 1) -			newptr = ptr_to_indirect(newptr); -		root->rnode = newptr; +		slot = to_free->slots[0]; +		if (root->height > 1) { +			slot->parent = NULL; +			slot = ptr_to_indirect(slot); +		} +		root->rnode = slot;  		root->height--;  		/* @@ -1257,97 +1300,120 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)  }  /** - *	radix_tree_delete    -    delete an item from a radix tree + *	__radix_tree_delete_node    -    try to free node after clearing a slot + *	@root:		radix tree root + *	@node:		node containing @index + * + *	After clearing the slot at @index in @node from radix tree + *	rooted at @root, call this function to attempt freeing the + *	node and shrinking the tree. + * + *	Returns %true if @node was freed, %false otherwise. + */ +bool __radix_tree_delete_node(struct radix_tree_root *root, +			      struct radix_tree_node *node) +{ +	bool deleted = false; + +	do { +		struct radix_tree_node *parent; + +		if (node->count) { +			if (node == indirect_to_ptr(root->rnode)) { +				radix_tree_shrink(root); +				if (root->height == 0) +					deleted = true; +			} +			return deleted; +		} + +		parent = node->parent; +		if (parent) { +			unsigned int offset; + +			offset = node->path >> RADIX_TREE_HEIGHT_SHIFT; +			parent->slots[offset] = NULL; +			parent->count--; +		} else { +			root_tag_clear_all(root); +			root->height = 0; +			root->rnode = NULL; +		} + +		radix_tree_node_free(node); +		deleted = true; + +		node = parent; +	} while (node); + +	return deleted; +} + +/** + *	radix_tree_delete_item    -    delete an item from a radix tree   *	@root:		radix tree root   *	@index:		index key + *	@item:		expected item   * - *	Remove the item at @index from the radix tree rooted at @root. + *	Remove @item at @index from the radix tree rooted at @root.   * - *	Returns the address of the deleted item, or NULL if it was not present. + *	Returns the address of the deleted item, or NULL if it was not present + *	or the entry at the given @index was not @item.   */ -void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) +void *radix_tree_delete_item(struct radix_tree_root *root, +			     unsigned long index, void *item)  { -	/* -	 * The radix tree path needs to be one longer than the maximum path -	 * since the "list" is null terminated. -	 */ -	struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path; -	struct radix_tree_node *slot = NULL; -	struct radix_tree_node *to_free; -	unsigned int height, shift; +	struct radix_tree_node *node; +	unsigned int offset; +	void **slot; +	void *entry;  	int tag; -	int offset; -	height = root->height; -	if (index > radix_tree_maxindex(height)) -		goto out; +	entry = __radix_tree_lookup(root, index, &node, &slot); +	if (!entry) +		return NULL; -	slot = root->rnode; -	if (height == 0) { +	if (item && entry != item) +		return NULL; + +	if (!node) {  		root_tag_clear_all(root);  		root->rnode = NULL; -		goto out; +		return entry;  	} -	slot = indirect_to_ptr(slot); - -	shift = (height - 1) * RADIX_TREE_MAP_SHIFT; -	pathp->node = NULL; - -	do { -		if (slot == NULL) -			goto out; - -		pathp++; -		offset = (index >> shift) & RADIX_TREE_MAP_MASK; -		pathp->offset = offset; -		pathp->node = slot; -		slot = slot->slots[offset]; -		shift -= RADIX_TREE_MAP_SHIFT; -		height--; -	} while (height > 0); -	if (slot == NULL) -		goto out; +	offset = index & RADIX_TREE_MAP_MASK;  	/* -	 * Clear all tags associated with the just-deleted item +	 * Clear all tags associated with the item to be deleted. +	 * This way of doing it would be inefficient, but seldom is any set.  	 */  	for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { -		if (tag_get(pathp->node, tag, pathp->offset)) +		if (tag_get(node, tag, offset))  			radix_tree_tag_clear(root, index, tag);  	} -	to_free = NULL; -	/* Now free the nodes we do not need anymore */ -	while (pathp->node) { -		pathp->node->slots[pathp->offset] = NULL; -		pathp->node->count--; -		/* -		 * Queue the node for deferred freeing after the -		 * last reference to it disappears (set NULL, above). -		 */ -		if (to_free) -			radix_tree_node_free(to_free); - -		if (pathp->node->count) { -			if (pathp->node == indirect_to_ptr(root->rnode)) -				radix_tree_shrink(root); -			goto out; -		} +	node->slots[offset] = NULL; +	node->count--; -		/* Node with zero slots in use so free it */ -		to_free = pathp->node; -		pathp--; +	__radix_tree_delete_node(root, node); -	} -	root_tag_clear_all(root); -	root->height = 0; -	root->rnode = NULL; -	if (to_free) -		radix_tree_node_free(to_free); +	return entry; +} +EXPORT_SYMBOL(radix_tree_delete_item); -out: -	return slot; +/** + *	radix_tree_delete    -    delete an item from a radix tree + *	@root:		radix tree root + *	@index:		index key + * + *	Remove the item at @index from the radix tree rooted at @root. + * + *	Returns the address of the deleted item, or NULL if it was not present. + */ +void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) +{ +	return radix_tree_delete_item(root, index, NULL);  }  EXPORT_SYMBOL(radix_tree_delete); @@ -1363,9 +1429,12 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag)  EXPORT_SYMBOL(radix_tree_tagged);  static void -radix_tree_node_ctor(void *node) +radix_tree_node_ctor(void *arg)  { -	memset(node, 0, sizeof(struct radix_tree_node)); +	struct radix_tree_node *node = arg; + +	memset(node, 0, sizeof(*node)); +	INIT_LIST_HEAD(&node->private_list);  }  static __init unsigned long __maxindex(unsigned int height)  | 
