1*eda14cbcSMatt Macy /* 2*eda14cbcSMatt Macy * CDDL HEADER START 3*eda14cbcSMatt Macy * 4*eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5*eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6*eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7*eda14cbcSMatt Macy * 8*eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*eda14cbcSMatt Macy * or http://www.opensolaris.org/os/licensing. 10*eda14cbcSMatt Macy * See the License for the specific language governing permissions 11*eda14cbcSMatt Macy * and limitations under the License. 12*eda14cbcSMatt Macy * 13*eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14*eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16*eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17*eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18*eda14cbcSMatt Macy * 19*eda14cbcSMatt Macy * CDDL HEADER END 20*eda14cbcSMatt Macy */ 21*eda14cbcSMatt Macy /* 22*eda14cbcSMatt Macy * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*eda14cbcSMatt Macy * Use is subject to license terms. 24*eda14cbcSMatt Macy */ 25*eda14cbcSMatt Macy 26*eda14cbcSMatt Macy 27*eda14cbcSMatt Macy 28*eda14cbcSMatt Macy #include <sys/zfs_context.h> 29*eda14cbcSMatt Macy #include <sys/avl.h> 30*eda14cbcSMatt Macy #include <sys/unique.h> 31*eda14cbcSMatt Macy 32*eda14cbcSMatt Macy static avl_tree_t unique_avl; 33*eda14cbcSMatt Macy static kmutex_t unique_mtx; 34*eda14cbcSMatt Macy 35*eda14cbcSMatt Macy typedef struct unique { 36*eda14cbcSMatt Macy avl_node_t un_link; 37*eda14cbcSMatt Macy uint64_t un_value; 38*eda14cbcSMatt Macy } unique_t; 39*eda14cbcSMatt Macy 40*eda14cbcSMatt Macy #define UNIQUE_MASK ((1ULL << UNIQUE_BITS) - 1) 41*eda14cbcSMatt Macy 42*eda14cbcSMatt Macy static int 43*eda14cbcSMatt Macy unique_compare(const void *a, const void *b) 44*eda14cbcSMatt Macy { 45*eda14cbcSMatt Macy const unique_t *una = (const unique_t *)a; 46*eda14cbcSMatt Macy const unique_t *unb = (const unique_t *)b; 47*eda14cbcSMatt Macy 48*eda14cbcSMatt Macy return (TREE_CMP(una->un_value, unb->un_value)); 49*eda14cbcSMatt Macy } 50*eda14cbcSMatt Macy 51*eda14cbcSMatt Macy void 52*eda14cbcSMatt Macy unique_init(void) 53*eda14cbcSMatt Macy { 54*eda14cbcSMatt Macy avl_create(&unique_avl, unique_compare, 55*eda14cbcSMatt Macy sizeof (unique_t), offsetof(unique_t, un_link)); 56*eda14cbcSMatt Macy mutex_init(&unique_mtx, NULL, MUTEX_DEFAULT, NULL); 57*eda14cbcSMatt Macy } 58*eda14cbcSMatt Macy 59*eda14cbcSMatt Macy void 60*eda14cbcSMatt Macy unique_fini(void) 61*eda14cbcSMatt Macy { 62*eda14cbcSMatt Macy avl_destroy(&unique_avl); 63*eda14cbcSMatt Macy mutex_destroy(&unique_mtx); 64*eda14cbcSMatt Macy } 65*eda14cbcSMatt Macy 66*eda14cbcSMatt Macy uint64_t 67*eda14cbcSMatt Macy unique_create(void) 68*eda14cbcSMatt Macy { 69*eda14cbcSMatt Macy uint64_t value = unique_insert(0); 70*eda14cbcSMatt Macy unique_remove(value); 71*eda14cbcSMatt Macy return (value); 72*eda14cbcSMatt Macy } 73*eda14cbcSMatt Macy 74*eda14cbcSMatt Macy uint64_t 75*eda14cbcSMatt Macy unique_insert(uint64_t value) 76*eda14cbcSMatt Macy { 77*eda14cbcSMatt Macy avl_index_t idx; 78*eda14cbcSMatt Macy unique_t *un = kmem_alloc(sizeof (unique_t), KM_SLEEP); 79*eda14cbcSMatt Macy 80*eda14cbcSMatt Macy un->un_value = value; 81*eda14cbcSMatt Macy 82*eda14cbcSMatt Macy mutex_enter(&unique_mtx); 83*eda14cbcSMatt Macy while (un->un_value == 0 || un->un_value & ~UNIQUE_MASK || 84*eda14cbcSMatt Macy avl_find(&unique_avl, un, &idx)) { 85*eda14cbcSMatt Macy mutex_exit(&unique_mtx); 86*eda14cbcSMatt Macy (void) random_get_pseudo_bytes((void*)&un->un_value, 87*eda14cbcSMatt Macy sizeof (un->un_value)); 88*eda14cbcSMatt Macy un->un_value &= UNIQUE_MASK; 89*eda14cbcSMatt Macy mutex_enter(&unique_mtx); 90*eda14cbcSMatt Macy } 91*eda14cbcSMatt Macy 92*eda14cbcSMatt Macy avl_insert(&unique_avl, un, idx); 93*eda14cbcSMatt Macy mutex_exit(&unique_mtx); 94*eda14cbcSMatt Macy 95*eda14cbcSMatt Macy return (un->un_value); 96*eda14cbcSMatt Macy } 97*eda14cbcSMatt Macy 98*eda14cbcSMatt Macy void 99*eda14cbcSMatt Macy unique_remove(uint64_t value) 100*eda14cbcSMatt Macy { 101*eda14cbcSMatt Macy unique_t un_tofind; 102*eda14cbcSMatt Macy unique_t *un; 103*eda14cbcSMatt Macy 104*eda14cbcSMatt Macy un_tofind.un_value = value; 105*eda14cbcSMatt Macy mutex_enter(&unique_mtx); 106*eda14cbcSMatt Macy un = avl_find(&unique_avl, &un_tofind, NULL); 107*eda14cbcSMatt Macy if (un != NULL) { 108*eda14cbcSMatt Macy avl_remove(&unique_avl, un); 109*eda14cbcSMatt Macy kmem_free(un, sizeof (unique_t)); 110*eda14cbcSMatt Macy } 111*eda14cbcSMatt Macy mutex_exit(&unique_mtx); 112*eda14cbcSMatt Macy } 113