Blame view

lib/radix-tree.c 39.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   * Copyright (C) 2001 Momchil Velikov
   * Portions Copyright (C) 2001 Christoph Hellwig
cde535359   Christoph Lameter   Christoph has moved
4
   * Copyright (C) 2005 SGI, Christoph Lameter
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
5
   * Copyright (C) 2006 Nick Piggin
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
6
   * Copyright (C) 2012 Konstantin Khlebnikov
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
   * published by the Free Software Foundation; either version 2, or (at
   * your option) any later version.
   *
   * This program is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   */
  
  #include <linux/errno.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
8bc3bcc93   Paul Gortmaker   lib: reduce the u...
26
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
  #include <linux/radix-tree.h>
  #include <linux/percpu.h>
  #include <linux/slab.h>
ce80b067d   Catalin Marinas   lib/radix-tree.c:...
30
  #include <linux/kmemleak.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
  #include <linux/notifier.h>
  #include <linux/cpu.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  #include <linux/string.h>
  #include <linux/bitops.h>
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
35
  #include <linux/rcupdate.h>
92cf21187   Frederic Weisbecker   sched/preempt: Me...
36
  #include <linux/preempt.h>		/* in_interrupt() */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

26fb1589c   Jeff Moyer   fix the max path ...
38
39
40
41
42
  /*
   * The height_to_maxindex array needs to be one deeper than the maximum
   * path as height 0 holds only 1 entry.
   */
  static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
  
  /*
   * Radix tree node cache.
   */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
47
  static struct kmem_cache *radix_tree_node_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
  
  /*
553680529   Nick Piggin   radix-tree: fix p...
50
51
52
53
54
55
56
57
58
59
60
61
62
   * 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)
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
   * Per-cpu pool of preloaded nodes
   */
  struct radix_tree_preload {
  	int nr;
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
67
68
  	/* nodes->private_data points to next preallocated node */
  	struct radix_tree_node *nodes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69
  };
8cef7d57a   Harvey Harrison   lib: radix_tree.c...
70
  static DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71

27d20fddc   Nick Piggin   radix-tree: fix R...
72
73
74
75
76
77
78
79
80
  static inline void *ptr_to_indirect(void *ptr)
  {
  	return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
  }
  
  static inline void *indirect_to_ptr(void *ptr)
  {
  	return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
  }
612d6c19d   Nick Piggin   [PATCH] radix-tre...
81
82
83
84
  static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
  {
  	return root->gfp_mask & __GFP_BITS_MASK;
  }
643b52b9c   Nick Piggin   radix-tree: fix s...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  static inline void tag_set(struct radix_tree_node *node, unsigned int tag,
  		int offset)
  {
  	__set_bit(offset, node->tags[tag]);
  }
  
  static inline void tag_clear(struct radix_tree_node *node, unsigned int tag,
  		int offset)
  {
  	__clear_bit(offset, node->tags[tag]);
  }
  
  static inline int tag_get(struct radix_tree_node *node, unsigned int tag,
  		int offset)
  {
  	return test_bit(offset, node->tags[tag]);
  }
  
  static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag)
  {
  	root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT));
  }
  
  static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag)
  {
  	root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT));
  }
  
  static inline void root_tag_clear_all(struct radix_tree_root *root)
  {
  	root->gfp_mask &= __GFP_BITS_MASK;
  }
  
  static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag)
  {
  	return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT));
  }
  
  /*
   * Returns 1 if any slot in the node has this tag set.
   * Otherwise returns 0.
   */
  static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag)
  {
  	int idx;
  	for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
  		if (node->tags[tag][idx])
  			return 1;
  	}
  	return 0;
  }
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  
  /**
   * 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;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
175
176
177
178
  /*
   * This assumes that the caller has performed appropriate preallocation, and
   * that the caller has pinned this thread of control to the current CPU.
   */
  static struct radix_tree_node *
  radix_tree_node_alloc(struct radix_tree_root *root)
  {
e2848a0ef   Nick Piggin   radix-tree: avoid...
179
  	struct radix_tree_node *ret = NULL;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
180
  	gfp_t gfp_mask = root_gfp_mask(root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181

5e4c0d974   Jan Kara   lib/radix-tree.c:...
182
183
184
185
186
187
  	/*
  	 * 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()) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  		struct radix_tree_preload *rtp;
e2848a0ef   Nick Piggin   radix-tree: avoid...
189
190
191
192
193
  		/*
  		 * Provided the caller has preloaded here, we will always
  		 * succeed in getting a node here (and never reach
  		 * kmem_cache_alloc)
  		 */
7c8e0181e   Christoph Lameter   mm: replace __get...
194
  		rtp = this_cpu_ptr(&radix_tree_preloads);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  		if (rtp->nr) {
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
196
197
198
  			ret = rtp->nodes;
  			rtp->nodes = ret->private_data;
  			ret->private_data = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
  			rtp->nr--;
  		}
ce80b067d   Catalin Marinas   lib/radix-tree.c:...
201
202
203
204
205
  		/*
  		 * Update the allocation stack trace as this is more useful
  		 * for debugging.
  		 */
  		kmemleak_update_trace(ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  	}
e2848a0ef   Nick Piggin   radix-tree: avoid...
207
  	if (ret == NULL)
488514d17   Christoph Lameter   Remove set_migrat...
208
  		ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
e2848a0ef   Nick Piggin   radix-tree: avoid...
209

c0bc9875b   Nick Piggin   radix-tree: use i...
210
  	BUG_ON(radix_tree_is_indirect_ptr(ret));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
  	return ret;
  }
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
213
214
215
216
  static void radix_tree_node_rcu_free(struct rcu_head *head)
  {
  	struct radix_tree_node *node =
  			container_of(head, struct radix_tree_node, rcu_head);
b6dd08652   Dave Chinner   radix-tree: clear...
217
  	int i;
643b52b9c   Nick Piggin   radix-tree: fix s...
218
219
220
221
222
223
  
  	/*
  	 * must only free zeroed nodes into the slab. radix_tree_shrink
  	 * can leave us with a non-NULL entry in the first slot, so clear
  	 * that here to make sure.
  	 */
b6dd08652   Dave Chinner   radix-tree: clear...
224
225
  	for (i = 0; i < RADIX_TREE_MAX_TAGS; i++)
  		tag_clear(node, i, 0);
643b52b9c   Nick Piggin   radix-tree: fix s...
226
227
  	node->slots[0] = NULL;
  	node->count = 0;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
228
229
  	kmem_cache_free(radix_tree_node_cachep, node);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
  static inline void
  radix_tree_node_free(struct radix_tree_node *node)
  {
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
233
  	call_rcu(&node->rcu_head, radix_tree_node_rcu_free);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
238
239
240
  }
  
  /*
   * 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.
b34df792b   David Howells   FS-Cache: Use rad...
241
242
243
   *
   * To make use of this facility, the radix tree must be initialised without
   * __GFP_WAIT being passed to INIT_RADIX_TREE().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
   */
5e4c0d974   Jan Kara   lib/radix-tree.c:...
245
  static int __radix_tree_preload(gfp_t gfp_mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
248
249
250
251
  {
  	struct radix_tree_preload *rtp;
  	struct radix_tree_node *node;
  	int ret = -ENOMEM;
  
  	preempt_disable();
7c8e0181e   Christoph Lameter   mm: replace __get...
252
  	rtp = this_cpu_ptr(&radix_tree_preloads);
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
253
  	while (rtp->nr < RADIX_TREE_PRELOAD_SIZE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
  		preempt_enable();
488514d17   Christoph Lameter   Remove set_migrat...
255
  		node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
  		if (node == NULL)
  			goto out;
  		preempt_disable();
7c8e0181e   Christoph Lameter   mm: replace __get...
259
  		rtp = this_cpu_ptr(&radix_tree_preloads);
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
260
261
262
263
264
  		if (rtp->nr < RADIX_TREE_PRELOAD_SIZE) {
  			node->private_data = rtp->nodes;
  			rtp->nodes = node;
  			rtp->nr++;
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  			kmem_cache_free(radix_tree_node_cachep, node);
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
266
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
269
270
271
  	}
  	ret = 0;
  out:
  	return ret;
  }
5e4c0d974   Jan Kara   lib/radix-tree.c:...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  
  /*
   * 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);
  }
d7f0923d8   David Chinner   [LIB]: export rad...
288
  EXPORT_SYMBOL(radix_tree_preload);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289

6e954b9e9   Nick Piggin   [PATCH] radix tre...
290
  /*
5e4c0d974   Jan Kara   lib/radix-tree.c:...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
   * 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);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
308
309
310
311
312
313
314
315
316
317
318
319
   *	Return the maximum key which can be store into a
   *	radix tree with height HEIGHT.
   */
  static inline unsigned long radix_tree_maxindex(unsigned int height)
  {
  	return height_to_maxindex[height];
  }
  
  /*
   *	Extend a radix tree so it can store key @index.
   */
  static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
  {
  	struct radix_tree_node *node;
e2bdb933a   Hugh Dickins   radix_tree: take ...
320
  	struct radix_tree_node *slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
  	unsigned int height;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
326
327
328
329
330
331
332
  	int tag;
  
  	/* Figure out what the height should be.  */
  	height = root->height + 1;
  	while (index > radix_tree_maxindex(height))
  		height++;
  
  	if (root->rnode == NULL) {
  		root->height = height;
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
  	do {
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
334
  		unsigned int newheight;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
336
  		if (!(node = radix_tree_node_alloc(root)))
  			return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  		/* Propagate the aggregated tag info into the new root */
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
338
  		for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
612d6c19d   Nick Piggin   [PATCH] radix-tre...
339
  			if (root_tag_get(root, tag))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
  				tag_set(node, tag, 0);
  		}
e2bdb933a   Hugh Dickins   radix_tree: take ...
342
  		/* Increase the height.  */
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
343
  		newheight = root->height+1;
449dd6984   Johannes Weiner   mm: keep page cac...
344
345
  		BUG_ON(newheight & ~RADIX_TREE_HEIGHT_MASK);
  		node->path = newheight;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  		node->count = 1;
e2bdb933a   Hugh Dickins   radix_tree: take ...
347
348
349
350
351
352
353
  		node->parent = NULL;
  		slot = root->rnode;
  		if (newheight > 1) {
  			slot = indirect_to_ptr(slot);
  			slot->parent = node;
  		}
  		node->slots[0] = slot;
27d20fddc   Nick Piggin   radix-tree: fix R...
354
  		node = ptr_to_indirect(node);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
355
356
  		rcu_assign_pointer(root->rnode, node);
  		root->height = newheight;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
360
361
362
  	} while (height > root->height);
  out:
  	return 0;
  }
  
  /**
139e56166   Johannes Weiner   lib: radix_tree: ...
363
   *	__radix_tree_create	-	create a slot in a radix tree
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
   *	@root:		radix tree root
   *	@index:		index key
139e56166   Johannes Weiner   lib: radix_tree: ...
366
367
   *	@nodep:		returns node
   *	@slotp:		returns slot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
   *
139e56166   Johannes Weiner   lib: radix_tree: ...
369
370
371
372
373
374
375
376
   *	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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
   */
139e56166   Johannes Weiner   lib: radix_tree: ...
378
379
  int __radix_tree_create(struct radix_tree_root *root, unsigned long index,
  			struct radix_tree_node **nodep, void ***slotp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  {
201b6264f   Christoph Lameter   [PATCH] radix-tre...
381
  	struct radix_tree_node *node = NULL, *slot;
139e56166   Johannes Weiner   lib: radix_tree: ...
382
  	unsigned int height, shift, offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
  	int error;
  
  	/* Make sure the tree is high enough.  */
612d6c19d   Nick Piggin   [PATCH] radix-tre...
386
  	if (index > radix_tree_maxindex(root->height)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
387
388
389
390
  		error = radix_tree_extend(root, index);
  		if (error)
  			return error;
  	}
27d20fddc   Nick Piggin   radix-tree: fix R...
391
  	slot = indirect_to_ptr(root->rnode);
c0bc9875b   Nick Piggin   radix-tree: use i...
392

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
396
  	height = root->height;
  	shift = (height-1) * RADIX_TREE_MAP_SHIFT;
  
  	offset = 0;			/* uninitialised var warning */
612d6c19d   Nick Piggin   [PATCH] radix-tre...
397
  	while (height > 0) {
201b6264f   Christoph Lameter   [PATCH] radix-tre...
398
  		if (slot == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  			/* Have to add a child node.  */
201b6264f   Christoph Lameter   [PATCH] radix-tre...
400
  			if (!(slot = radix_tree_node_alloc(root)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  				return -ENOMEM;
449dd6984   Johannes Weiner   mm: keep page cac...
402
  			slot->path = height;
e2bdb933a   Hugh Dickins   radix_tree: take ...
403
  			slot->parent = node;
201b6264f   Christoph Lameter   [PATCH] radix-tre...
404
  			if (node) {
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
405
  				rcu_assign_pointer(node->slots[offset], slot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
  				node->count++;
449dd6984   Johannes Weiner   mm: keep page cac...
407
  				slot->path |= offset << RADIX_TREE_HEIGHT_SHIFT;
201b6264f   Christoph Lameter   [PATCH] radix-tre...
408
  			} else
27d20fddc   Nick Piggin   radix-tree: fix R...
409
  				rcu_assign_pointer(root->rnode, ptr_to_indirect(slot));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
413
  		}
  
  		/* Go a level down */
  		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
201b6264f   Christoph Lameter   [PATCH] radix-tre...
414
415
  		node = slot;
  		slot = node->slots[offset];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
  		shift -= RADIX_TREE_MAP_SHIFT;
  		height--;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
418
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419

139e56166   Johannes Weiner   lib: radix_tree: ...
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
  	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)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
  		return -EEXIST;
139e56166   Johannes Weiner   lib: radix_tree: ...
449
  	rcu_assign_pointer(*slot, item);
201b6264f   Christoph Lameter   [PATCH] radix-tre...
450

612d6c19d   Nick Piggin   [PATCH] radix-tre...
451
452
  	if (node) {
  		node->count++;
139e56166   Johannes Weiner   lib: radix_tree: ...
453
454
  		BUG_ON(tag_get(node, 0, index & RADIX_TREE_MAP_MASK));
  		BUG_ON(tag_get(node, 1, index & RADIX_TREE_MAP_MASK));
612d6c19d   Nick Piggin   [PATCH] radix-tre...
455
  	} else {
612d6c19d   Nick Piggin   [PATCH] radix-tre...
456
457
458
  		BUG_ON(root_tag_get(root, 0));
  		BUG_ON(root_tag_get(root, 1));
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
461
462
  	return 0;
  }
  EXPORT_SYMBOL(radix_tree_insert);
139e56166   Johannes Weiner   lib: radix_tree: ...
463
464
465
466
467
468
469
470
471
472
473
474
475
  /**
   *	__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.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
476
   */
139e56166   Johannes Weiner   lib: radix_tree: ...
477
478
  void *__radix_tree_lookup(struct radix_tree_root *root, unsigned long index,
  			  struct radix_tree_node **nodep, void ***slotp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
  {
139e56166   Johannes Weiner   lib: radix_tree: ...
480
  	struct radix_tree_node *node, *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  	unsigned int height, shift;
139e56166   Johannes Weiner   lib: radix_tree: ...
482
  	void **slot;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
483

2676a58c9   Paul E. McKenney   radix-tree: Disab...
484
  	node = rcu_dereference_raw(root->rnode);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
485
  	if (node == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  		return NULL;
c0bc9875b   Nick Piggin   radix-tree: use i...
487
  	if (!radix_tree_is_indirect_ptr(node)) {
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
488
489
  		if (index > 0)
  			return NULL;
139e56166   Johannes Weiner   lib: radix_tree: ...
490
491
492
493
494
495
  
  		if (nodep)
  			*nodep = NULL;
  		if (slotp)
  			*slotp = (void **)&root->rnode;
  		return node;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
496
  	}
27d20fddc   Nick Piggin   radix-tree: fix R...
497
  	node = indirect_to_ptr(node);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
498

449dd6984   Johannes Weiner   mm: keep page cac...
499
  	height = node->path & RADIX_TREE_HEIGHT_MASK;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
500
501
  	if (index > radix_tree_maxindex(height))
  		return NULL;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
502

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
  	shift = (height-1) * RADIX_TREE_MAP_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504

7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
505
  	do {
139e56166   Johannes Weiner   lib: radix_tree: ...
506
507
  		parent = node;
  		slot = node->slots + ((index >> shift) & RADIX_TREE_MAP_MASK);
2676a58c9   Paul E. McKenney   radix-tree: Disab...
508
  		node = rcu_dereference_raw(*slot);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
509
  		if (node == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
  			return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
512
  		shift -= RADIX_TREE_MAP_SHIFT;
  		height--;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
513
  	} while (height > 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514

139e56166   Johannes Weiner   lib: radix_tree: ...
515
516
517
518
519
  	if (nodep)
  		*nodep = parent;
  	if (slotp)
  		*slotp = slot;
  	return node;
b72b71c6c   Huang Shijie   lib: do code opti...
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
  }
  
  /**
   *	radix_tree_lookup_slot    -    lookup a slot in a radix tree
   *	@root:		radix tree root
   *	@index:		index key
   *
   *	Returns:  the slot corresponding to the position @index in the
   *	radix tree @root. This is useful for update-if-exists operations.
   *
   *	This function can be called under rcu_read_lock iff the slot is not
   *	modified by radix_tree_replace_slot, otherwise it must be called
   *	exclusive from other writers. Any dereference of the slot must be done
   *	using radix_tree_deref_slot.
   */
  void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
  {
139e56166   Johannes Weiner   lib: radix_tree: ...
537
538
539
540
541
  	void **slot;
  
  	if (!__radix_tree_lookup(root, index, NULL, &slot))
  		return NULL;
  	return slot;
a43313668   Hans Reiser   [PATCH] reiser4: ...
542
  }
a43313668   Hans Reiser   [PATCH] reiser4: ...
543
544
545
546
547
548
549
550
  EXPORT_SYMBOL(radix_tree_lookup_slot);
  
  /**
   *	radix_tree_lookup    -    perform lookup operation on a radix tree
   *	@root:		radix tree root
   *	@index:		index key
   *
   *	Lookup the item at the position @index in the radix tree @root.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
551
552
553
554
555
   *
   *	This function can be called under rcu_read_lock, however the caller
   *	must manage lifetimes of leaf nodes (eg. RCU may also be used to free
   *	them safely). No RCU barriers are required to access or modify the
   *	returned item, however.
a43313668   Hans Reiser   [PATCH] reiser4: ...
556
557
558
   */
  void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
  {
139e56166   Johannes Weiner   lib: radix_tree: ...
559
  	return __radix_tree_lookup(root, index, NULL, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
561
562
563
564
565
566
567
568
  }
  EXPORT_SYMBOL(radix_tree_lookup);
  
  /**
   *	radix_tree_tag_set - set a tag on a radix tree node
   *	@root:		radix tree root
   *	@index:		index key
   *	@tag: 		tag index
   *
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
569
570
   *	Set the search tag (which must be < RADIX_TREE_MAX_TAGS)
   *	corresponding to @index in the radix tree.  From
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
574
575
576
   *	the root all the way down to the leaf node.
   *
   *	Returns the address of the tagged item.   Setting a tag on a not-present
   *	item is a bug.
   */
  void *radix_tree_tag_set(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
577
  			unsigned long index, unsigned int tag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
  {
  	unsigned int height, shift;
201b6264f   Christoph Lameter   [PATCH] radix-tre...
580
  	struct radix_tree_node *slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
  
  	height = root->height;
4c91c3648   Peter Zijlstra   [PATCH] buglet in...
583
  	BUG_ON(index > radix_tree_maxindex(height));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584

27d20fddc   Nick Piggin   radix-tree: fix R...
585
  	slot = indirect_to_ptr(root->rnode);
612d6c19d   Nick Piggin   [PATCH] radix-tre...
586
  	shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
588
589
590
591
  
  	while (height > 0) {
  		int offset;
  
  		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
d5274261e   Nick Piggin   [PATCH] radix tre...
592
593
  		if (!tag_get(slot, tag, offset))
  			tag_set(slot, tag, offset);
201b6264f   Christoph Lameter   [PATCH] radix-tre...
594
595
  		slot = slot->slots[offset];
  		BUG_ON(slot == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
598
  		shift -= RADIX_TREE_MAP_SHIFT;
  		height--;
  	}
612d6c19d   Nick Piggin   [PATCH] radix-tre...
599
600
601
  	/* set the root's tag bit */
  	if (slot && !root_tag_get(root, tag))
  		root_tag_set(root, tag);
201b6264f   Christoph Lameter   [PATCH] radix-tre...
602
  	return slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
604
605
606
607
608
609
610
611
  }
  EXPORT_SYMBOL(radix_tree_tag_set);
  
  /**
   *	radix_tree_tag_clear - clear a tag on a radix tree node
   *	@root:		radix tree root
   *	@index:		index key
   *	@tag: 		tag index
   *
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
612
613
   *	Clear the search tag (which must be < RADIX_TREE_MAX_TAGS)
   *	corresponding to @index in the radix tree.  If
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
615
616
617
618
619
620
   *	this causes the leaf node to have no tags set then clear the tag in the
   *	next-to-leaf node, etc.
   *
   *	Returns the address of the tagged item on success, else NULL.  ie:
   *	has the same return value and semantics as radix_tree_lookup().
   */
  void *radix_tree_tag_clear(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
621
  			unsigned long index, unsigned int tag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  {
e2bdb933a   Hugh Dickins   radix_tree: take ...
623
  	struct radix_tree_node *node = NULL;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
624
  	struct radix_tree_node *slot = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625
  	unsigned int height, shift;
e2bdb933a   Hugh Dickins   radix_tree: take ...
626
  	int uninitialized_var(offset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627
628
629
630
  
  	height = root->height;
  	if (index > radix_tree_maxindex(height))
  		goto out;
e2bdb933a   Hugh Dickins   radix_tree: take ...
631
  	shift = height * RADIX_TREE_MAP_SHIFT;
27d20fddc   Nick Piggin   radix-tree: fix R...
632
  	slot = indirect_to_ptr(root->rnode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633

e2bdb933a   Hugh Dickins   radix_tree: take ...
634
  	while (shift) {
201b6264f   Christoph Lameter   [PATCH] radix-tre...
635
  		if (slot == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  			goto out;
e2bdb933a   Hugh Dickins   radix_tree: take ...
637
  		shift -= RADIX_TREE_MAP_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
e2bdb933a   Hugh Dickins   radix_tree: take ...
639
  		node = slot;
201b6264f   Christoph Lameter   [PATCH] radix-tre...
640
  		slot = slot->slots[offset];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  	}
612d6c19d   Nick Piggin   [PATCH] radix-tre...
642
  	if (slot == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
  		goto out;
e2bdb933a   Hugh Dickins   radix_tree: take ...
644
645
  	while (node) {
  		if (!tag_get(node, tag, offset))
d5274261e   Nick Piggin   [PATCH] radix tre...
646
  			goto out;
e2bdb933a   Hugh Dickins   radix_tree: take ...
647
648
  		tag_clear(node, tag, offset);
  		if (any_tag_set(node, tag))
6e954b9e9   Nick Piggin   [PATCH] radix tre...
649
  			goto out;
e2bdb933a   Hugh Dickins   radix_tree: take ...
650
651
652
653
  
  		index >>= RADIX_TREE_MAP_SHIFT;
  		offset = index & RADIX_TREE_MAP_MASK;
  		node = node->parent;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
654
655
656
657
658
  	}
  
  	/* clear the root's tag bit */
  	if (root_tag_get(root, tag))
  		root_tag_clear(root, tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  out:
612d6c19d   Nick Piggin   [PATCH] radix-tre...
660
  	return slot;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
661
662
  }
  EXPORT_SYMBOL(radix_tree_tag_clear);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
  /**
32605a181   Marcelo Tosatti   [PATCH] radix_tag...
664
665
666
   * radix_tree_tag_get - get a tag on a radix tree node
   * @root:		radix tree root
   * @index:		index key
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
667
   * @tag: 		tag index (< RADIX_TREE_MAX_TAGS)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
   *
32605a181   Marcelo Tosatti   [PATCH] radix_tag...
669
   * Return values:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
   *
612d6c19d   Nick Piggin   [PATCH] radix-tre...
671
672
   *  0: tag not present or not set
   *  1: tag set
ce82653d6   David Howells   radix_tree_tag_ge...
673
674
675
676
   *
   * Note that the return value of this function may not be relied on, even if
   * the RCU lock is held, unless tag modification and node deletion are excluded
   * from concurrency.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
678
   */
  int radix_tree_tag_get(struct radix_tree_root *root,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
679
  			unsigned long index, unsigned int tag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
  {
  	unsigned int height, shift;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
682
  	struct radix_tree_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
683

612d6c19d   Nick Piggin   [PATCH] radix-tre...
684
685
686
  	/* check the root's tag bit */
  	if (!root_tag_get(root, tag))
  		return 0;
2676a58c9   Paul E. McKenney   radix-tree: Disab...
687
  	node = rcu_dereference_raw(root->rnode);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
688
689
  	if (node == NULL)
  		return 0;
c0bc9875b   Nick Piggin   radix-tree: use i...
690
  	if (!radix_tree_is_indirect_ptr(node))
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
691
  		return (index == 0);
27d20fddc   Nick Piggin   radix-tree: fix R...
692
  	node = indirect_to_ptr(node);
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
693

449dd6984   Johannes Weiner   mm: keep page cac...
694
  	height = node->path & RADIX_TREE_HEIGHT_MASK;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
695
696
  	if (index > radix_tree_maxindex(height))
  		return 0;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
697

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
  	shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
700
701
  
  	for ( ; ; ) {
  		int offset;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
702
  		if (node == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
705
  			return 0;
  
  		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
706
  		if (!tag_get(node, tag, offset))
3fa36acbc   Hugh Dickins   radix_tree: clean...
707
  			return 0;
ce82653d6   David Howells   radix_tree_tag_ge...
708
  		if (height == 1)
3fa36acbc   Hugh Dickins   radix_tree: clean...
709
  			return 1;
2676a58c9   Paul E. McKenney   radix-tree: Disab...
710
  		node = rcu_dereference_raw(node->slots[offset]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
711
712
713
714
715
  		shift -= RADIX_TREE_MAP_SHIFT;
  		height--;
  	}
  }
  EXPORT_SYMBOL(radix_tree_tag_get);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716

6df8ba4f8   Fengguang Wu   radixtree: introd...
717
  /**
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
718
719
720
721
722
723
724
725
726
727
728
729
   * 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;
449dd6984   Johannes Weiner   mm: keep page cac...
730
  	unsigned long index, offset, height;
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
731
732
733
734
735
736
737
738
739
  
  	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.
fffaee365   Konstantin Khlebnikov   radix-tree: fix c...
740
741
742
  	 *
  	 * This condition also used by radix_tree_next_slot() to stop
  	 * contiguous iterating, and forbid swithing to the next chunk.
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
  	 */
  	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:
449dd6984   Johannes Weiner   mm: keep page cac...
761
762
  	height = rnode->path & RADIX_TREE_HEIGHT_MASK;
  	shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
78c1d7848   Konstantin Khlebnikov   radix-tree: intro...
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
  	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);
  
  /**
ebf8aa44b   Jan Kara   radix-tree: omple...
835
836
837
838
839
840
841
842
843
844
845
846
847
848
   * 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
   * @first_indexp:	pointer to a starting index of a range to scan
   * @last_index:		last index of a range to scan
   * @nr_to_tag:		maximum number items to tag
   * @iftag:		tag index to test
   * @settag:		tag index to set if tested tag is set
   *
   * This function scans range of radix tree from first_index to last_index
   * (inclusive).  For each item in the range if iftag is set, the function sets
   * also settag. The function stops either after tagging nr_to_tag items or
   * after reaching last_index.
   *
144dcfc01   Dave Chinner   radix-tree: radix...
849
850
851
852
853
854
855
   * The tags must be set from the leaf level only and propagated back up the
   * path to the root. We must do this so that we resolve the full path before
   * setting any tags on intermediate nodes. If we set tags as we descend, then
   * we can get to the leaf node and find that the index that has the iftag
   * set is outside the range we are scanning. This reults in dangling tags and
   * can lead to problems with later tag operations (e.g. livelocks on lookups).
   *
ebf8aa44b   Jan Kara   radix-tree: omple...
856
857
   * The function returns number of leaves where the tag was set and sets
   * *first_indexp to the first unscanned index.
d5ed3a4af   Jan Kara   lib/radix-tree.c:...
858
859
   * WARNING! *first_indexp can wrap if last_index is ULONG_MAX. Caller must
   * be prepared to handle that.
ebf8aa44b   Jan Kara   radix-tree: omple...
860
861
862
863
864
865
   */
  unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root,
  		unsigned long *first_indexp, unsigned long last_index,
  		unsigned long nr_to_tag,
  		unsigned int iftag, unsigned int settag)
  {
144dcfc01   Dave Chinner   radix-tree: radix...
866
  	unsigned int height = root->height;
e2bdb933a   Hugh Dickins   radix_tree: take ...
867
  	struct radix_tree_node *node = NULL;
144dcfc01   Dave Chinner   radix-tree: radix...
868
869
870
871
  	struct radix_tree_node *slot;
  	unsigned int shift;
  	unsigned long tagged = 0;
  	unsigned long index = *first_indexp;
ebf8aa44b   Jan Kara   radix-tree: omple...
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
  
  	last_index = min(last_index, radix_tree_maxindex(height));
  	if (index > last_index)
  		return 0;
  	if (!nr_to_tag)
  		return 0;
  	if (!root_tag_get(root, iftag)) {
  		*first_indexp = last_index + 1;
  		return 0;
  	}
  	if (height == 0) {
  		*first_indexp = last_index + 1;
  		root_tag_set(root, settag);
  		return 1;
  	}
  
  	shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
27d20fddc   Nick Piggin   radix-tree: fix R...
889
  	slot = indirect_to_ptr(root->rnode);
ebf8aa44b   Jan Kara   radix-tree: omple...
890
891
  
  	for (;;) {
e2bdb933a   Hugh Dickins   radix_tree: take ...
892
  		unsigned long upindex;
ebf8aa44b   Jan Kara   radix-tree: omple...
893
894
895
896
897
898
899
  		int offset;
  
  		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
  		if (!slot->slots[offset])
  			goto next;
  		if (!tag_get(slot, iftag, offset))
  			goto next;
e2bdb933a   Hugh Dickins   radix_tree: take ...
900
  		if (shift) {
144dcfc01   Dave Chinner   radix-tree: radix...
901
  			/* Go down one level */
144dcfc01   Dave Chinner   radix-tree: radix...
902
  			shift -= RADIX_TREE_MAP_SHIFT;
e2bdb933a   Hugh Dickins   radix_tree: take ...
903
  			node = slot;
144dcfc01   Dave Chinner   radix-tree: radix...
904
905
906
907
908
909
  			slot = slot->slots[offset];
  			continue;
  		}
  
  		/* tag the leaf */
  		tagged++;
ebf8aa44b   Jan Kara   radix-tree: omple...
910
  		tag_set(slot, settag, offset);
144dcfc01   Dave Chinner   radix-tree: radix...
911
912
  
  		/* walk back up the path tagging interior nodes */
e2bdb933a   Hugh Dickins   radix_tree: take ...
913
914
915
916
  		upindex = index;
  		while (node) {
  			upindex >>= RADIX_TREE_MAP_SHIFT;
  			offset = upindex & RADIX_TREE_MAP_MASK;
144dcfc01   Dave Chinner   radix-tree: radix...
917
  			/* stop if we find a node with the tag already set */
e2bdb933a   Hugh Dickins   radix_tree: take ...
918
  			if (tag_get(node, settag, offset))
144dcfc01   Dave Chinner   radix-tree: radix...
919
  				break;
e2bdb933a   Hugh Dickins   radix_tree: take ...
920
921
  			tag_set(node, settag, offset);
  			node = node->parent;
ebf8aa44b   Jan Kara   radix-tree: omple...
922
  		}
144dcfc01   Dave Chinner   radix-tree: radix...
923

e2bdb933a   Hugh Dickins   radix_tree: take ...
924
925
926
927
928
929
930
931
  		/*
  		 * 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;
ebf8aa44b   Jan Kara   radix-tree: omple...
932
933
934
  next:
  		/* Go to next item at level determined by 'shift' */
  		index = ((index >> shift) + 1) << shift;
d5ed3a4af   Jan Kara   lib/radix-tree.c:...
935
936
  		/* Overflow can happen when last_index is ~0UL... */
  		if (index > last_index || !index)
ebf8aa44b   Jan Kara   radix-tree: omple...
937
938
939
940
941
942
943
944
945
  			break;
  		if (tagged >= nr_to_tag)
  			break;
  		while (((index >> shift) & RADIX_TREE_MAP_MASK) == 0) {
  			/*
  			 * We've fully scanned this node. Go up. Because
  			 * last_index is guaranteed to be in the tree, what
  			 * we do below cannot wander astray.
  			 */
e2bdb933a   Hugh Dickins   radix_tree: take ...
946
  			slot = slot->parent;
ebf8aa44b   Jan Kara   radix-tree: omple...
947
948
949
950
  			shift += RADIX_TREE_MAP_SHIFT;
  		}
  	}
  	/*
ac15ee691   Toshiyuki Okajima   radix_tree: radix...
951
952
  	 * 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.
ebf8aa44b   Jan Kara   radix-tree: omple...
953
  	 */
ac15ee691   Toshiyuki Okajima   radix_tree: radix...
954
955
  	if (tagged > 0)
  		root_tag_set(root, settag);
ebf8aa44b   Jan Kara   radix-tree: omple...
956
957
958
959
960
  	*first_indexp = index;
  
  	return tagged;
  }
  EXPORT_SYMBOL(radix_tree_range_tag_if_tagged);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
962
963
964
965
966
967
968
969
970
971
972
  /**
   *	radix_tree_gang_lookup - perform multiple lookup on a radix tree
   *	@root:		radix tree root
   *	@results:	where the results of the lookup are placed
   *	@first_index:	start the lookup from this key
   *	@max_items:	place up to this many items at *results
   *
   *	Performs an index-ascending scan of the tree for present items.  Places
   *	them at *@results and returns the number of items which were placed at
   *	*@results.
   *
   *	The implementation is naive.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
973
974
975
976
977
978
   *
   *	Like radix_tree_lookup, radix_tree_gang_lookup may be called under
   *	rcu_read_lock. In this case, rather than the returned results being
   *	an atomic snapshot of the tree at a single point in time, the semantics
   *	of an RCU protected gang lookup are as though multiple radix_tree_lookups
   *	have been issued in individual locks, and results stored in 'results'.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
981
982
983
   */
  unsigned int
  radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
  			unsigned long first_index, unsigned int max_items)
  {
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
984
985
986
  	struct radix_tree_iter iter;
  	void **slot;
  	unsigned int ret = 0;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
987

cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
988
  	if (unlikely(!max_items))
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
989
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990

cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
991
992
993
994
995
  	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)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
996
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
  	}
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
998

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
1000
1001
  	return ret;
  }
  EXPORT_SYMBOL(radix_tree_gang_lookup);
47feff2c8   Nick Piggin   radix-tree: add g...
1002
1003
1004
1005
  /**
   *	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
6328650bb   Hugh Dickins   radix_tree: excep...
1006
   *	@indices:	where their indices should be placed (but usually NULL)
47feff2c8   Nick Piggin   radix-tree: add g...
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
   *	@first_index:	start the lookup from this key
   *	@max_items:	place up to this many items at *results
   *
   *	Performs an index-ascending scan of the tree for present items.  Places
   *	their slots at *@results and returns the number of items which were
   *	placed at *@results.
   *
   *	The implementation is naive.
   *
   *	Like radix_tree_gang_lookup as far as RCU and locking goes. Slots must
   *	be dereferenced with radix_tree_deref_slot, and if using only RCU
   *	protection, radix_tree_deref_slot may fail requiring a retry.
   */
  unsigned int
6328650bb   Hugh Dickins   radix_tree: excep...
1021
1022
  radix_tree_gang_lookup_slot(struct radix_tree_root *root,
  			void ***results, unsigned long *indices,
47feff2c8   Nick Piggin   radix-tree: add g...
1023
1024
  			unsigned long first_index, unsigned int max_items)
  {
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1025
1026
1027
  	struct radix_tree_iter iter;
  	void **slot;
  	unsigned int ret = 0;
47feff2c8   Nick Piggin   radix-tree: add g...
1028

cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1029
  	if (unlikely(!max_items))
47feff2c8   Nick Piggin   radix-tree: add g...
1030
  		return 0;
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1031
1032
  	radix_tree_for_each_slot(slot, root, &iter, first_index) {
  		results[ret] = slot;
6328650bb   Hugh Dickins   radix_tree: excep...
1033
  		if (indices)
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1034
1035
  			indices[ret] = iter.index;
  		if (++ret == max_items)
47feff2c8   Nick Piggin   radix-tree: add g...
1036
  			break;
47feff2c8   Nick Piggin   radix-tree: add g...
1037
1038
1039
1040
1041
  	}
  
  	return ret;
  }
  EXPORT_SYMBOL(radix_tree_gang_lookup_slot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
1043
1044
1045
1046
1047
1048
  /**
   *	radix_tree_gang_lookup_tag - perform multiple lookup on a radix tree
   *	                             based on a tag
   *	@root:		radix tree root
   *	@results:	where the results of the lookup are placed
   *	@first_index:	start the lookup from this key
   *	@max_items:	place up to this many items at *results
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
1049
   *	@tag:		the tag index (< RADIX_TREE_MAX_TAGS)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
1051
1052
1053
1054
1055
1056
   *
   *	Performs an index-ascending scan of the tree for present items which
   *	have the tag indexed by @tag set.  Places the items at *@results and
   *	returns the number of items which were placed at *@results.
   */
  unsigned int
  radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
1057
1058
  		unsigned long first_index, unsigned int max_items,
  		unsigned int tag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1059
  {
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1060
1061
1062
  	struct radix_tree_iter iter;
  	void **slot;
  	unsigned int ret = 0;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1063

cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1064
  	if (unlikely(!max_items))
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
1065
  		return 0;
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1066
1067
1068
1069
1070
  	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)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072
  	}
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
1073

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
1075
1076
1077
1078
  	return ret;
  }
  EXPORT_SYMBOL(radix_tree_gang_lookup_tag);
  
  /**
47feff2c8   Nick Piggin   radix-tree: add g...
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
   *	radix_tree_gang_lookup_tag_slot - perform multiple slot lookup on a
   *					  radix tree based on a tag
   *	@root:		radix tree root
   *	@results:	where the results of the lookup are placed
   *	@first_index:	start the lookup from this key
   *	@max_items:	place up to this many items at *results
   *	@tag:		the tag index (< RADIX_TREE_MAX_TAGS)
   *
   *	Performs an index-ascending scan of the tree for present items which
   *	have the tag indexed by @tag set.  Places the slots at *@results and
   *	returns the number of slots which were placed at *@results.
   */
  unsigned int
  radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results,
  		unsigned long first_index, unsigned int max_items,
  		unsigned int tag)
  {
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1096
1097
1098
  	struct radix_tree_iter iter;
  	void **slot;
  	unsigned int ret = 0;
47feff2c8   Nick Piggin   radix-tree: add g...
1099

cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1100
  	if (unlikely(!max_items))
47feff2c8   Nick Piggin   radix-tree: add g...
1101
  		return 0;
cebbd29e1   Konstantin Khlebnikov   radix-tree: rewri...
1102
1103
1104
  	radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
  		results[ret] = slot;
  		if (++ret == max_items)
47feff2c8   Nick Piggin   radix-tree: add g...
1105
  			break;
47feff2c8   Nick Piggin   radix-tree: add g...
1106
1107
1108
1109
1110
  	}
  
  	return ret;
  }
  EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot);
e504f3fdd   Hugh Dickins   tmpfs radix_tree:...
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
  #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;
449dd6984   Johannes Weiner   mm: keep page cac...
1122
  	height = slot->path & RADIX_TREE_HEIGHT_MASK;
e504f3fdd   Hugh Dickins   tmpfs radix_tree:...
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
  	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: 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;
  }
  
  /**
   *	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;
  
  	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;
  		}
  
  		node = indirect_to_ptr(node);
449dd6984   Johannes Weiner   mm: keep page cac...
1185
1186
  		max_index = radix_tree_maxindex(node->path &
  						RADIX_TREE_HEIGHT_MASK);
5f30fc94c   Hugh Dickins   lib/radix-tree.c:...
1187
1188
  		if (cur_index > max_index) {
  			rcu_read_unlock();
e504f3fdd   Hugh Dickins   tmpfs radix_tree:...
1189
  			break;
5f30fc94c   Hugh Dickins   lib/radix-tree.c:...
1190
  		}
e504f3fdd   Hugh Dickins   tmpfs radix_tree:...
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
  
  		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 */
47feff2c8   Nick Piggin   radix-tree: add g...
1205
1206
  
  /**
a5f51c966   Nick Piggin   [PATCH] radix-tre...
1207
1208
1209
1210
1211
1212
   *	radix_tree_shrink    -    shrink height of a radix tree to minimal
   *	@root		radix tree root
   */
  static inline void radix_tree_shrink(struct radix_tree_root *root)
  {
  	/* try to shrink tree height */
c0bc9875b   Nick Piggin   radix-tree: use i...
1213
  	while (root->height > 0) {
a5f51c966   Nick Piggin   [PATCH] radix-tre...
1214
  		struct radix_tree_node *to_free = root->rnode;
e2bdb933a   Hugh Dickins   radix_tree: take ...
1215
  		struct radix_tree_node *slot;
a5f51c966   Nick Piggin   [PATCH] radix-tre...
1216

c0bc9875b   Nick Piggin   radix-tree: use i...
1217
  		BUG_ON(!radix_tree_is_indirect_ptr(to_free));
27d20fddc   Nick Piggin   radix-tree: fix R...
1218
  		to_free = indirect_to_ptr(to_free);
c0bc9875b   Nick Piggin   radix-tree: use i...
1219
1220
1221
1222
1223
1224
1225
1226
1227
  
  		/*
  		 * The candidate node has more than one child, or its child
  		 * is not at the leftmost slot, we cannot shrink.
  		 */
  		if (to_free->count != 1)
  			break;
  		if (!to_free->slots[0])
  			break;
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
1228
1229
  		/*
  		 * We don't need rcu_assign_pointer(), since we are simply
27d20fddc   Nick Piggin   radix-tree: fix R...
1230
1231
  		 * moving the node from one part of the tree to another: if it
  		 * was safe to dereference the old pointer to it
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
1232
  		 * (to_free->slots[0]), it will be safe to dereference the new
27d20fddc   Nick Piggin   radix-tree: fix R...
1233
  		 * one (root->rnode) as far as dependent read barriers go.
7cf9c2c76   Nick Piggin   [PATCH] radix-tre...
1234
  		 */
e2bdb933a   Hugh Dickins   radix_tree: take ...
1235
1236
1237
1238
1239
1240
  		slot = to_free->slots[0];
  		if (root->height > 1) {
  			slot->parent = NULL;
  			slot = ptr_to_indirect(slot);
  		}
  		root->rnode = slot;
a5f51c966   Nick Piggin   [PATCH] radix-tre...
1241
  		root->height--;
27d20fddc   Nick Piggin   radix-tree: fix R...
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
  
  		/*
  		 * We have a dilemma here. The node's slot[0] must not be
  		 * NULLed in case there are concurrent lookups expecting to
  		 * find the item. However if this was a bottom-level node,
  		 * then it may be subject to the slot pointer being visible
  		 * to callers dereferencing it. If item corresponding to
  		 * slot[0] is subsequently deleted, these callers would expect
  		 * their slot to become empty sooner or later.
  		 *
  		 * For example, lockless pagecache will look up a slot, deref
  		 * the page pointer, and if the page is 0 refcount it means it
  		 * was concurrently deleted from pagecache so try the deref
  		 * again. Fortunately there is already a requirement for logic
  		 * to retry the entire slot lookup -- the indirect pointer
  		 * problem (replacing direct root node with an indirect pointer
  		 * 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;
a5f51c966   Nick Piggin   [PATCH] radix-tre...
1264
1265
1266
1267
1268
  		radix_tree_node_free(to_free);
  	}
  }
  
  /**
139e56166   Johannes Weiner   lib: radix_tree: ...
1269
1270
   *	__radix_tree_delete_node    -    try to free node after clearing a slot
   *	@root:		radix tree root
139e56166   Johannes Weiner   lib: radix_tree: ...
1271
1272
1273
1274
1275
1276
1277
1278
   *	@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.
   */
449dd6984   Johannes Weiner   mm: keep page cac...
1279
  bool __radix_tree_delete_node(struct radix_tree_root *root,
139e56166   Johannes Weiner   lib: radix_tree: ...
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
  			      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) {
449dd6984   Johannes Weiner   mm: keep page cac...
1298
  			unsigned int offset;
139e56166   Johannes Weiner   lib: radix_tree: ...
1299

449dd6984   Johannes Weiner   mm: keep page cac...
1300
1301
  			offset = node->path >> RADIX_TREE_HEIGHT_SHIFT;
  			parent->slots[offset] = NULL;
139e56166   Johannes Weiner   lib: radix_tree: ...
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
  			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;
  }
  
  /**
53c59f262   Johannes Weiner   lib: radix-tree: ...
1319
   *	radix_tree_delete_item    -    delete an item from a radix tree
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320
1321
   *	@root:		radix tree root
   *	@index:		index key
53c59f262   Johannes Weiner   lib: radix-tree: ...
1322
   *	@item:		expected item
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
   *
53c59f262   Johannes Weiner   lib: radix-tree: ...
1324
   *	Remove @item at @index from the radix tree rooted at @root.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1325
   *
53c59f262   Johannes Weiner   lib: radix-tree: ...
1326
1327
   *	Returns the address of the deleted item, or NULL if it was not present
   *	or the entry at the given @index was not @item.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1328
   */
53c59f262   Johannes Weiner   lib: radix-tree: ...
1329
1330
  void *radix_tree_delete_item(struct radix_tree_root *root,
  			     unsigned long index, void *item)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1331
  {
139e56166   Johannes Weiner   lib: radix_tree: ...
1332
1333
1334
1335
  	struct radix_tree_node *node;
  	unsigned int offset;
  	void **slot;
  	void *entry;
d5274261e   Nick Piggin   [PATCH] radix tre...
1336
  	int tag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1337

139e56166   Johannes Weiner   lib: radix_tree: ...
1338
1339
1340
  	entry = __radix_tree_lookup(root, index, &node, &slot);
  	if (!entry)
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1341

139e56166   Johannes Weiner   lib: radix_tree: ...
1342
1343
1344
1345
  	if (item && entry != item)
  		return NULL;
  
  	if (!node) {
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1346
1347
  		root_tag_clear_all(root);
  		root->rnode = NULL;
139e56166   Johannes Weiner   lib: radix_tree: ...
1348
  		return entry;
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1349
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350

139e56166   Johannes Weiner   lib: radix_tree: ...
1351
  	offset = index & RADIX_TREE_MAP_MASK;
53c59f262   Johannes Weiner   lib: radix-tree: ...
1352

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  	/*
e2bdb933a   Hugh Dickins   radix_tree: take ...
1354
1355
  	 * Clear all tags associated with the item to be deleted.
  	 * This way of doing it would be inefficient, but seldom is any set.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
  	 */
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
1357
  	for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
e2bdb933a   Hugh Dickins   radix_tree: take ...
1358
  		if (tag_get(node, tag, offset))
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1359
  			radix_tree_tag_clear(root, index, tag);
d5274261e   Nick Piggin   [PATCH] radix tre...
1360
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1361

139e56166   Johannes Weiner   lib: radix_tree: ...
1362
1363
  	node->slots[offset] = NULL;
  	node->count--;
e2bdb933a   Hugh Dickins   radix_tree: take ...
1364

449dd6984   Johannes Weiner   mm: keep page cac...
1365
  	__radix_tree_delete_node(root, node);
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1366

139e56166   Johannes Weiner   lib: radix_tree: ...
1367
  	return entry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1368
  }
53c59f262   Johannes Weiner   lib: radix-tree: ...
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
  EXPORT_SYMBOL(radix_tree_delete_item);
  
  /**
   *	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);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1384
1385
1386
1387
1388
1389
1390
  EXPORT_SYMBOL(radix_tree_delete);
  
  /**
   *	radix_tree_tagged - test whether any items in the tree are tagged
   *	@root:		radix tree root
   *	@tag:		tag to test
   */
daff89f32   Jonathan Corbet   [PATCH] radix-tre...
1391
  int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1392
  {
612d6c19d   Nick Piggin   [PATCH] radix-tre...
1393
  	return root_tag_get(root, tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
1395
1396
1397
  }
  EXPORT_SYMBOL(radix_tree_tagged);
  
  static void
449dd6984   Johannes Weiner   mm: keep page cac...
1398
  radix_tree_node_ctor(void *arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1399
  {
449dd6984   Johannes Weiner   mm: keep page cac...
1400
1401
1402
1403
  	struct radix_tree_node *node = arg;
  
  	memset(node, 0, sizeof(*node));
  	INIT_LIST_HEAD(&node->private_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1404
1405
1406
1407
  }
  
  static __init unsigned long __maxindex(unsigned int height)
  {
430d275a3   Peter Lund   avoid negative (a...
1408
1409
1410
1411
1412
1413
1414
1415
  	unsigned int width = height * RADIX_TREE_MAP_SHIFT;
  	int shift = RADIX_TREE_INDEX_BITS - width;
  
  	if (shift < 0)
  		return ~0UL;
  	if (shift >= BITS_PER_LONG)
  		return 0UL;
  	return ~0UL >> shift;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
1417
1418
1419
1420
1421
1422
1423
1424
  }
  
  static __init void radix_tree_init_maxindex(void)
  {
  	unsigned int i;
  
  	for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++)
  		height_to_maxindex[i] = __maxindex(i);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1425
1426
1427
1428
1429
1430
  static int radix_tree_callback(struct notifier_block *nfb,
                              unsigned long action,
                              void *hcpu)
  {
         int cpu = (long)hcpu;
         struct radix_tree_preload *rtp;
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
1431
         struct radix_tree_node *node;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1432
1433
  
         /* Free per-cpu pool of perloaded nodes */
8bb784428   Rafael J. Wysocki   Add suspend-relat...
1434
         if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
1436
                 rtp = &per_cpu(radix_tree_preloads, cpu);
                 while (rtp->nr) {
9d2a8da00   Kirill A. Shutemov   radix-tree: repla...
1437
1438
1439
1440
  			node = rtp->nodes;
  			rtp->nodes = node->private_data;
  			kmem_cache_free(radix_tree_node_cachep, node);
  			rtp->nr--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
1442
1443
1444
                 }
         }
         return NOTIFY_OK;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1445
1446
1447
1448
1449
  
  void __init radix_tree_init(void)
  {
  	radix_tree_node_cachep = kmem_cache_create("radix_tree_node",
  			sizeof(struct radix_tree_node), 0,
488514d17   Christoph Lameter   Remove set_migrat...
1450
1451
  			SLAB_PANIC | SLAB_RECLAIM_ACCOUNT,
  			radix_tree_node_ctor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
1454
  	radix_tree_init_maxindex();
  	hotcpu_notifier(radix_tree_callback, 0);
  }