Line data Source code
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, see <http://www.gnu.org/licenses/>. 25 : */ 26 : 27 : /* 28 : see the section marked "public interface" below for documentation 29 : */ 30 : 31 : /** 32 : * @file 33 : */ 34 : 35 : #include "replace.h" 36 : #include "samba_util.h" /* generate_random() */ 37 : #include "idtree.h" 38 : #include "idtree_random.h" 39 : 40 : /** 41 : allocate a new id randomly in the given range 42 : */ 43 649065 : _PUBLIC_ int idr_get_new_random(struct idr_context *idp, 44 : void *ptr, 45 : int starting_id, 46 : int limit) 47 : { 48 3055 : int id; 49 : 50 : /* first try a random starting point in the whole range, and if that fails, 51 : then start randomly in the bottom half of the range. This can only 52 : fail if the range is over half full, and finally fallback to any 53 : free id */ 54 655175 : id = idr_get_new_above( 55 649065 : idp, ptr, starting_id+(generate_random() % limit), limit); 56 649065 : if (id == -1) { 57 0 : id = idr_get_new_above( 58 : idp, 59 : ptr, 60 0 : starting_id+(generate_random()%(limit/2)), 61 : limit); 62 : } 63 649065 : if (id == -1) { 64 0 : id = idr_get_new_above(idp, ptr, starting_id, limit); 65 : } 66 : 67 649065 : return id; 68 : }