at v2.6.31 145 lines 3.3 kB view raw
1/* 2 * net/9p/util.c 3 * 4 * This file contains some helper functions 5 * 6 * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 12 * as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to: 21 * Free Software Foundation 22 * 51 Franklin Street, Fifth Floor 23 * Boston, MA 02111-1301 USA 24 * 25 */ 26 27#include <linux/module.h> 28#include <linux/errno.h> 29#include <linux/fs.h> 30#include <linux/sched.h> 31#include <linux/parser.h> 32#include <linux/idr.h> 33#include <net/9p/9p.h> 34 35/** 36 * struct p9_idpool - per-connection accounting for tag idpool 37 * @lock: protects the pool 38 * @pool: idr to allocate tag id from 39 * 40 */ 41 42struct p9_idpool { 43 spinlock_t lock; 44 struct idr pool; 45}; 46 47/** 48 * p9_idpool_create - create a new per-connection id pool 49 * 50 */ 51 52struct p9_idpool *p9_idpool_create(void) 53{ 54 struct p9_idpool *p; 55 56 p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL); 57 if (!p) 58 return ERR_PTR(-ENOMEM); 59 60 spin_lock_init(&p->lock); 61 idr_init(&p->pool); 62 63 return p; 64} 65EXPORT_SYMBOL(p9_idpool_create); 66 67/** 68 * p9_idpool_destroy - create a new per-connection id pool 69 * @p: idpool to destory 70 */ 71 72void p9_idpool_destroy(struct p9_idpool *p) 73{ 74 idr_destroy(&p->pool); 75 kfree(p); 76} 77EXPORT_SYMBOL(p9_idpool_destroy); 78 79/** 80 * p9_idpool_get - allocate numeric id from pool 81 * @p: pool to allocate from 82 * 83 * Bugs: This seems to be an awful generic function, should it be in idr.c with 84 * the lock included in struct idr? 85 */ 86 87int p9_idpool_get(struct p9_idpool *p) 88{ 89 int i = 0; 90 int error; 91 unsigned long flags; 92 93retry: 94 if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) 95 return 0; 96 97 spin_lock_irqsave(&p->lock, flags); 98 99 /* no need to store exactly p, we just need something non-null */ 100 error = idr_get_new(&p->pool, p, &i); 101 spin_unlock_irqrestore(&p->lock, flags); 102 103 if (error == -EAGAIN) 104 goto retry; 105 else if (error) 106 return -1; 107 108 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", i, p); 109 return i; 110} 111EXPORT_SYMBOL(p9_idpool_get); 112 113/** 114 * p9_idpool_put - release numeric id from pool 115 * @id: numeric id which is being released 116 * @p: pool to release id into 117 * 118 * Bugs: This seems to be an awful generic function, should it be in idr.c with 119 * the lock included in struct idr? 120 */ 121 122void p9_idpool_put(int id, struct p9_idpool *p) 123{ 124 unsigned long flags; 125 126 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", id, p); 127 128 spin_lock_irqsave(&p->lock, flags); 129 idr_remove(&p->pool, id); 130 spin_unlock_irqrestore(&p->lock, flags); 131} 132EXPORT_SYMBOL(p9_idpool_put); 133 134/** 135 * p9_idpool_check - check if the specified id is available 136 * @id: id to check 137 * @p: pool to check 138 */ 139 140int p9_idpool_check(int id, struct p9_idpool *p) 141{ 142 return idr_find(&p->pool, id) != NULL; 143} 144EXPORT_SYMBOL(p9_idpool_check); 145