2 * Implementation of the extensible bitmap type.
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/errno.h>
12 int ebitmap_cmp(struct ebitmap
*e1
, struct ebitmap
*e2
)
14 struct ebitmap_node
*n1
, *n2
;
16 if (e1
->highbit
!= e2
->highbit
)
22 (n1
->startbit
== n2
->startbit
) &&
23 (n1
->map
== n2
->map
)) {
34 int ebitmap_cpy(struct ebitmap
*dst
, struct ebitmap
*src
)
36 struct ebitmap_node
*n
, *new, *prev
;
42 new = kmalloc(sizeof(*new), GFP_ATOMIC
);
47 memset(new, 0, sizeof(*new));
48 new->startbit
= n
->startbit
;
59 dst
->highbit
= src
->highbit
;
63 int ebitmap_contains(struct ebitmap
*e1
, struct ebitmap
*e2
)
65 struct ebitmap_node
*n1
, *n2
;
67 if (e1
->highbit
< e2
->highbit
)
72 while (n1
&& n2
&& (n1
->startbit
<= n2
->startbit
)) {
73 if (n1
->startbit
< n2
->startbit
) {
77 if ((n1
->map
& n2
->map
) != n2
->map
)
90 int ebitmap_get_bit(struct ebitmap
*e
, unsigned long bit
)
92 struct ebitmap_node
*n
;
98 while (n
&& (n
->startbit
<= bit
)) {
99 if ((n
->startbit
+ MAPSIZE
) > bit
) {
100 if (n
->map
& (MAPBIT
<< (bit
- n
->startbit
)))
111 int ebitmap_set_bit(struct ebitmap
*e
, unsigned long bit
, int value
)
113 struct ebitmap_node
*n
, *prev
, *new;
117 while (n
&& n
->startbit
<= bit
) {
118 if ((n
->startbit
+ MAPSIZE
) > bit
) {
120 n
->map
|= (MAPBIT
<< (bit
- n
->startbit
));
122 n
->map
&= ~(MAPBIT
<< (bit
- n
->startbit
));
124 /* drop this node from the bitmap */
128 * this was the highest map
132 e
->highbit
= prev
->startbit
+ MAPSIZE
;
137 prev
->next
= n
->next
;
153 new = kmalloc(sizeof(*new), GFP_ATOMIC
);
156 memset(new, 0, sizeof(*new));
158 new->startbit
= bit
& ~(MAPSIZE
- 1);
159 new->map
= (MAPBIT
<< (bit
- new->startbit
));
162 /* this node will be the highest map within the bitmap */
163 e
->highbit
= new->startbit
+ MAPSIZE
;
166 new->next
= prev
->next
;
176 void ebitmap_destroy(struct ebitmap
*e
)
178 struct ebitmap_node
*n
, *temp
;
195 int ebitmap_read(struct ebitmap
*e
, void *fp
)
198 struct ebitmap_node
*n
, *l
;
199 u32 buf
[3], mapsize
, count
, i
;
204 rc
= next_entry(buf
, fp
, sizeof buf
);
208 mapsize
= le32_to_cpu(buf
[0]);
209 e
->highbit
= le32_to_cpu(buf
[1]);
210 count
= le32_to_cpu(buf
[2]);
212 if (mapsize
!= MAPSIZE
) {
213 printk(KERN_ERR
"security: ebitmap: map size %u does not "
214 "match my size %Zd (high bit was %d)\n", mapsize
,
215 MAPSIZE
, e
->highbit
);
222 if (e
->highbit
& (MAPSIZE
- 1)) {
223 printk(KERN_ERR
"security: ebitmap: high bit (%d) is not a "
224 "multiple of the map size (%Zd)\n", e
->highbit
, MAPSIZE
);
228 for (i
= 0; i
< count
; i
++) {
229 rc
= next_entry(buf
, fp
, sizeof(u32
));
231 printk(KERN_ERR
"security: ebitmap: truncated map\n");
234 n
= kmalloc(sizeof(*n
), GFP_KERNEL
);
236 printk(KERN_ERR
"security: ebitmap: out of memory\n");
240 memset(n
, 0, sizeof(*n
));
242 n
->startbit
= le32_to_cpu(buf
[0]);
244 if (n
->startbit
& (MAPSIZE
- 1)) {
245 printk(KERN_ERR
"security: ebitmap start bit (%d) is "
246 "not a multiple of the map size (%Zd)\n",
247 n
->startbit
, MAPSIZE
);
250 if (n
->startbit
> (e
->highbit
- MAPSIZE
)) {
251 printk(KERN_ERR
"security: ebitmap start bit (%d) is "
252 "beyond the end of the bitmap (%Zd)\n",
253 n
->startbit
, (e
->highbit
- MAPSIZE
));
256 rc
= next_entry(&map
, fp
, sizeof(u64
));
258 printk(KERN_ERR
"security: ebitmap: truncated map\n");
261 n
->map
= le64_to_cpu(map
);
264 printk(KERN_ERR
"security: ebitmap: null map in "
265 "ebitmap (startbit %d)\n", n
->startbit
);
269 if (n
->startbit
<= l
->startbit
) {
270 printk(KERN_ERR
"security: ebitmap: start "
271 "bit %d comes after start bit %d\n",
272 n
->startbit
, l
->startbit
);