1 /*
2    Unix SMB/CIFS implementation.
3 
4    very efficient functions to manage mapping a id (such as a fnum) to
5    a pointer. This is used for fnum and search id allocation.
6 
7    Copyright (C) Andrew Tridgell 2004
8 
9    This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
10    written by Jim Houston jim.houston@ccur.com, and is
11    Copyright (C) 2002 by Concurrent Computer Corporation
12 
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27 
28 /*
29   see the section marked "public interface" below for documentation
30 */
31 
32 /**
33  * @file
34  */
35 
36 #include "includes.h"
37 
38 #define IDR_BITS 5
39 #define IDR_FULL 0xfffffffful
40 #if 0 /* unused */
41 #define TOP_LEVEL_FULL (IDR_FULL >> 30)
42 #endif
43 #define IDR_SIZE (1 << IDR_BITS)
44 #define IDR_MASK ((1 << IDR_BITS)-1)
45 #define MAX_ID_SHIFT (sizeof(int)*8 - 1)
46 #define MAX_ID_BIT (1U << MAX_ID_SHIFT)
47 #define MAX_ID_MASK (MAX_ID_BIT - 1)
48 #define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
49 #define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
50 
51 #define set_bit(bit, v) (v) |= (1<<(bit))
52 #define clear_bit(bit, v) (v) &= ~(1<<(bit))
53 #define test_bit(bit, v) ((v) & (1<<(bit)))
54 
55 struct idr_layer {
56 	uint32_t		 bitmap;
57 	struct idr_layer	*ary[IDR_SIZE];
58 	int			 count;
59 };
60 
61 struct idr_context {
62 	struct idr_layer *top;
63 	struct idr_layer *id_free;
64 	int		  layers;
65 	int		  id_free_cnt;
66 };
67 
alloc_layer(struct idr_context * idp)68 static struct idr_layer *alloc_layer(struct idr_context *idp)
69 {
70 	struct idr_layer *p;
71 
72 	if (!(p = idp->id_free))
73 		return NULL;
74 	idp->id_free = p->ary[0];
75 	idp->id_free_cnt--;
76 	p->ary[0] = NULL;
77 	return p;
78 }
79 
find_next_bit(uint32_t bm,int maxid,int n)80 static int find_next_bit(uint32_t bm, int maxid, int n)
81 {
82 	while (n<maxid && !test_bit(n, bm)) n++;
83 	return n;
84 }
85 
free_layer(struct idr_context * idp,struct idr_layer * p)86 static void free_layer(struct idr_context *idp, struct idr_layer *p)
87 {
88 	p->ary[0] = idp->id_free;
89 	idp->id_free = p;
90 	idp->id_free_cnt++;
91 }
92 
idr_pre_get(struct idr_context * idp)93 static int idr_pre_get(struct idr_context *idp)
94 {
95 	while (idp->id_free_cnt < IDR_FREE_MAX) {
96 		struct idr_layer *new = talloc_zero(idp, struct idr_layer);
97 		if(new == NULL)
98 			return (0);
99 		free_layer(idp, new);
100 	}
101 	return 1;
102 }
103 
sub_alloc(struct idr_context * idp,void * ptr,int * starting_id)104 static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id)
105 {
106 	int n, m, sh;
107 	struct idr_layer *p, *new;
108 	struct idr_layer *pa[MAX_LEVEL];
109 	int l, id;
110 	uint32_t bm;
111 
112 	memset(pa, 0, sizeof(pa));
113 
114 	id = *starting_id;
115 	p = idp->top;
116 	l = idp->layers;
117 	pa[l--] = NULL;
118 	while (1) {
119 		/*
120 		 * We run around this while until we reach the leaf node...
121 		 */
122 		n = (id >> (IDR_BITS*l)) & IDR_MASK;
123 		bm = ~p->bitmap;
124 		m = find_next_bit(bm, IDR_SIZE, n);
125 		if (m == IDR_SIZE) {
126 			/* no space available go back to previous layer. */
127 			l++;
128 			id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
129 			if (!(p = pa[l])) {
130 				*starting_id = id;
131 				return -2;
132 			}
133 			continue;
134 		}
135 		if (m != n) {
136 			sh = IDR_BITS*l;
137 			id = ((id >> sh) ^ n ^ m) << sh;
138 		}
139 		if ((id >= MAX_ID_BIT) || (id < 0))
140 			return -1;
141 		if (l == 0)
142 			break;
143 		/*
144 		 * Create the layer below if it is missing.
145 		 */
146 		if (!p->ary[m]) {
147 			if (!(new = alloc_layer(idp)))
148 				return -1;
149 			p->ary[m] = new;
150 			p->count++;
151 		}
152 		pa[l--] = p;
153 		p = p->ary[m];
154 	}
155 	/*
156 	 * We have reached the leaf node, plant the
157 	 * users pointer and return the raw id.
158 	 */
159 	p->ary[m] = (struct idr_layer *)ptr;
160 	set_bit(m, p->bitmap);
161 	p->count++;
162 	/*
163 	 * If this layer is full mark the bit in the layer above
164 	 * to show that this part of the radix tree is full.
165 	 * This may complete the layer above and require walking
166 	 * up the radix tree.
167 	 */
168 	n = id;
169 	while (p->bitmap == IDR_FULL) {
170 		if (!(p = pa[++l]))
171 			break;
172 		n = n >> IDR_BITS;
173 		set_bit((n & IDR_MASK), p->bitmap);
174 	}
175 	return(id);
176 }
177 
idr_get_new_above_int(struct idr_context * idp,void * ptr,int starting_id)178 static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id)
179 {
180 	struct idr_layer *p, *new;
181 	int layers, v, id;
182 
183 	idr_pre_get(idp);
184 
185 	id = starting_id;
186 build_up:
187 	p = idp->top;
188 	layers = idp->layers;
189 	if (!p) {
190 		if (!(p = alloc_layer(idp)))
191 			return -1;
192 		layers = 1;
193 	}
194 	/*
195 	 * Add a new layer to the top of the tree if the requested
196 	 * id is larger than the currently allocated space.
197 	 */
198 	while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
199 		layers++;
200 		if (!p->count)
201 			continue;
202 		if (!(new = alloc_layer(idp))) {
203 			/*
204 			 * The allocation failed.  If we built part of
205 			 * the structure tear it down.
206 			 */
207 			for (new = p; p && p != idp->top; new = p) {
208 				p = p->ary[0];
209 				new->ary[0] = NULL;
210 				new->bitmap = new->count = 0;
211 				free_layer(idp, new);
212 			}
213 			return -1;
214 		}
215 		new->ary[0] = p;
216 		new->count = 1;
217 		if (p->bitmap == IDR_FULL)
218 			set_bit(0, new->bitmap);
219 		p = new;
220 	}
221 	idp->top = p;
222 	idp->layers = layers;
223 	v = sub_alloc(idp, ptr, &id);
224 	if (v == -2)
225 		goto build_up;
226 	return(v);
227 }
228 
sub_remove(struct idr_context * idp,int shift,int id)229 static int sub_remove(struct idr_context *idp, int shift, int id)
230 {
231 	struct idr_layer *p = idp->top;
232 	struct idr_layer **pa[MAX_LEVEL];
233 	struct idr_layer ***paa = &pa[0];
234 	int n;
235 
236 	*paa = NULL;
237 	*++paa = &idp->top;
238 
239 	while ((shift > 0) && p) {
240 		n = (id >> shift) & IDR_MASK;
241 		clear_bit(n, p->bitmap);
242 		*++paa = &p->ary[n];
243 		p = p->ary[n];
244 		shift -= IDR_BITS;
245 	}
246 	n = id & IDR_MASK;
247 	if (p != NULL && test_bit(n, p->bitmap)) {
248 		clear_bit(n, p->bitmap);
249 		p->ary[n] = NULL;
250 		while(*paa && ! --((**paa)->count)){
251 			free_layer(idp, **paa);
252 			**paa-- = NULL;
253 		}
254 		if ( ! *paa )
255 			idp->layers = 0;
256 		return 0;
257 	}
258 	return -1;
259 }
260 
_idr_find(struct idr_context * idp,int id)261 static void *_idr_find(struct idr_context *idp, int id)
262 {
263 	int n;
264 	struct idr_layer *p;
265 
266 	n = idp->layers * IDR_BITS;
267 	p = idp->top;
268 	/*
269 	 * This tests to see if bits outside the current tree are
270 	 * present.  If so, tain't one of ours!
271 	 */
272 	if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS))
273 	     return NULL;
274 
275 	/* Mask off upper bits we don't use for the search. */
276 	id &= MAX_ID_MASK;
277 
278 	while (n >= IDR_BITS && p) {
279 		n -= IDR_BITS;
280 		p = p->ary[(id >> n) & IDR_MASK];
281 	}
282 	return((void *)p);
283 }
284 
_idr_remove(struct idr_context * idp,int id)285 static int _idr_remove(struct idr_context *idp, int id)
286 {
287 	struct idr_layer *p;
288 
289 	/* Mask off upper bits we don't use for the search. */
290 	id &= MAX_ID_MASK;
291 
292 	if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) {
293 		return -1;
294 	}
295 
296 	if ( idp->top && idp->top->count == 1 &&
297 	     (idp->layers > 1) &&
298 	     idp->top->ary[0]) {
299 		/* We can drop a layer */
300 		p = idp->top->ary[0];
301 		idp->top->bitmap = idp->top->count = 0;
302 		free_layer(idp, idp->top);
303 		idp->top = p;
304 		--idp->layers;
305 	}
306 	while (idp->id_free_cnt >= IDR_FREE_MAX) {
307 		p = alloc_layer(idp);
308 		talloc_free(p);
309 	}
310 	return 0;
311 }
312 
313 /************************************************************************
314   this is the public interface
315 **************************************************************************/
316 
317 /**
318   initialise a idr tree. The context return value must be passed to
319   all subsequent idr calls. To destroy the idr tree use talloc_free()
320   on this context
321  */
idr_init(TALLOC_CTX * mem_ctx)322 _PUBLIC_ struct idr_context *idr_init(TALLOC_CTX *mem_ctx)
323 {
324 	return talloc_zero(mem_ctx, struct idr_context);
325 }
326 
327 /**
328   allocate the next available id, and assign 'ptr' into its slot.
329   you can retrieve later this pointer using idr_find()
330 */
idr_get_new(struct idr_context * idp,void * ptr,int limit)331 _PUBLIC_ int idr_get_new(struct idr_context *idp, void *ptr, int limit)
332 {
333 	int ret = idr_get_new_above_int(idp, ptr, 0);
334 	if (ret > limit) {
335 		idr_remove(idp, ret);
336 		return -1;
337 	}
338 	return ret;
339 }
340 
341 /**
342    allocate a new id, giving the first available value greater than or
343    equal to the given starting id
344 */
idr_get_new_above(struct idr_context * idp,void * ptr,int starting_id,int limit)345 _PUBLIC_ int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit)
346 {
347 	int ret = idr_get_new_above_int(idp, ptr, starting_id);
348 	if (ret > limit) {
349 		idr_remove(idp, ret);
350 		return -1;
351 	}
352 	return ret;
353 }
354 
355 /**
356   allocate a new id randomly in the given range
357 */
idr_get_new_random(struct idr_context * idp,void * ptr,int limit)358 _PUBLIC_ int idr_get_new_random(struct idr_context *idp, void *ptr, int limit)
359 {
360 	int id;
361 
362 	/* first try a random starting point in the whole range, and if that fails,
363 	   then start randomly in the bottom half of the range. This can only
364 	   fail if the range is over half full */
365 	id = idr_get_new_above(idp, ptr, 1+(generate_random() % limit), limit);
366 	if (id == -1) {
367 		id = idr_get_new_above(idp, ptr, 1+(generate_random()%(limit/2)), limit);
368 	}
369 
370 	return id;
371 }
372 
373 /**
374   find a pointer value previously set with idr_get_new given an id
375 */
idr_find(struct idr_context * idp,int id)376 _PUBLIC_ void *idr_find(struct idr_context *idp, int id)
377 {
378 	return _idr_find(idp, id);
379 }
380 
381 /**
382   remove an id from the idr tree
383 */
idr_remove(struct idr_context * idp,int id)384 _PUBLIC_ int idr_remove(struct idr_context *idp, int id)
385 {
386 	int ret;
387 	ret = _idr_remove((struct idr_context *)idp, id);
388 	if (ret != 0) {
389 		DEBUG(0,("WARNING: attempt to remove unset id %d in idtree\n", id));
390 	}
391 	return ret;
392 }
393