1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 <linux/slab.h>
34#include <net/9p/9p.h>
35
36
37
38
39
40
41
42
43struct p9_idpool {
44 spinlock_t lock;
45 struct idr pool;
46};
47
48
49
50
51
52
53struct p9_idpool *p9_idpool_create(void)
54{
55 struct p9_idpool *p;
56
57 p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
58 if (!p)
59 return ERR_PTR(-ENOMEM);
60
61 spin_lock_init(&p->lock);
62 idr_init(&p->pool);
63
64 return p;
65}
66EXPORT_SYMBOL(p9_idpool_create);
67
68
69
70
71
72
73void p9_idpool_destroy(struct p9_idpool *p)
74{
75 idr_destroy(&p->pool);
76 kfree(p);
77}
78EXPORT_SYMBOL(p9_idpool_destroy);
79
80
81
82
83
84
85
86
87
88int p9_idpool_get(struct p9_idpool *p)
89{
90 int i = 0;
91 int error;
92 unsigned long flags;
93
94retry:
95 if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
96 return 0;
97
98 spin_lock_irqsave(&p->lock, flags);
99
100
101 error = idr_get_new(&p->pool, p, &i);
102 spin_unlock_irqrestore(&p->lock, flags);
103
104 if (error == -EAGAIN)
105 goto retry;
106 else if (error)
107 return -1;
108
109 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
110 return i;
111}
112EXPORT_SYMBOL(p9_idpool_get);
113
114
115
116
117
118
119
120
121
122
123void p9_idpool_put(int id, struct p9_idpool *p)
124{
125 unsigned long flags;
126
127 P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
128
129 spin_lock_irqsave(&p->lock, flags);
130 idr_remove(&p->pool, id);
131 spin_unlock_irqrestore(&p->lock, flags);
132}
133EXPORT_SYMBOL(p9_idpool_put);
134
135
136
137
138
139
140
141int p9_idpool_check(int id, struct p9_idpool *p)
142{
143 return idr_find(&p->pool, id) != NULL;
144}
145EXPORT_SYMBOL(p9_idpool_check);
146
147