at v2.6.27 141 lines 3.2 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 return i; 109} 110EXPORT_SYMBOL(p9_idpool_get); 111 112/** 113 * p9_idpool_put - release numeric id from pool 114 * @id: numeric id which is being released 115 * @p: pool to release id into 116 * 117 * Bugs: This seems to be an awful generic function, should it be in idr.c with 118 * the lock included in struct idr? 119 */ 120 121void p9_idpool_put(int id, struct p9_idpool *p) 122{ 123 unsigned long flags; 124 spin_lock_irqsave(&p->lock, flags); 125 idr_remove(&p->pool, id); 126 spin_unlock_irqrestore(&p->lock, flags); 127} 128EXPORT_SYMBOL(p9_idpool_put); 129 130/** 131 * p9_idpool_check - check if the specified id is available 132 * @id: id to check 133 * @p: pool to check 134 */ 135 136int p9_idpool_check(int id, struct p9_idpool *p) 137{ 138 return idr_find(&p->pool, id) != NULL; 139} 140EXPORT_SYMBOL(p9_idpool_check); 141