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 = kzalloc(sizeof(*new), GFP_ATOMIC
);
47 new->startbit
= n
->startbit
;
58 dst
->highbit
= src
->highbit
;
62 int ebitmap_contains(struct ebitmap
*e1
, struct ebitmap
*e2
)
64 struct ebitmap_node
*n1
, *n2
;
66 if (e1
->highbit
< e2
->highbit
)
71 while (n1
&& n2
&& (n1
->startbit
<= n2
->startbit
)) {
72 if (n1
->startbit
< n2
->startbit
) {
76 if ((n1
->map
& n2
->map
) != n2
->map
)
89 int ebitmap_get_bit(struct ebitmap
*e
, unsigned long bit
)
91 struct ebitmap_node
*n
;
97 while (n
&& (n
->startbit
<= bit
)) {
98 if ((n
->startbit
+ MAPSIZE
) > bit
) {
99 if (n
->map
& (MAPBIT
<< (bit
- n
->startbit
)))
110 int ebitmap_set_bit(struct ebitmap
*e
, unsigned long bit
, int value
)
112 struct ebitmap_node
*n
, *prev
, *new;
116 while (n
&& n
->startbit
<= bit
) {
117 if ((n
->startbit
+ MAPSIZE
) > bit
) {
119 n
->map
|= (MAPBIT
<< (bit
- n
->startbit
));
121 n
->map
&= ~(MAPBIT
<< (bit
- n
->startbit
));
123 /* drop this node from the bitmap */
127 * this was the highest map
131 e
->highbit
= prev
->startbit
+ MAPSIZE
;
136 prev
->next
= n
->next
;
152 new = kzalloc(sizeof(*new), GFP_ATOMIC
);
156 new->startbit
= bit
& ~(MAPSIZE
- 1);
157 new->map
= (MAPBIT
<< (bit
- new->startbit
));
160 /* this node will be the highest map within the bitmap */
161 e
->highbit
= new->startbit
+ MAPSIZE
;
164 new->next
= prev
->next
;
174 void ebitmap_destroy(struct ebitmap
*e
)
176 struct ebitmap_node
*n
, *temp
;
193 int ebitmap_read(struct ebitmap
*e
, void *fp
)
196 struct ebitmap_node
*n
, *l
;
198 u32 mapsize
, count
, i
;
203 rc
= next_entry(buf
, fp
, sizeof buf
);
207 mapsize
= le32_to_cpu(buf
[0]);
208 e
->highbit
= le32_to_cpu(buf
[1]);
209 count
= le32_to_cpu(buf
[2]);
211 if (mapsize
!= MAPSIZE
) {
212 printk(KERN_ERR
"security: ebitmap: map size %u does not "
213 "match my size %Zd (high bit was %d)\n", mapsize
,
214 MAPSIZE
, e
->highbit
);
221 if (e
->highbit
& (MAPSIZE
- 1)) {
222 printk(KERN_ERR
"security: ebitmap: high bit (%d) is not a "
223 "multiple of the map size (%Zd)\n", e
->highbit
, MAPSIZE
);
227 for (i
= 0; i
< count
; i
++) {
228 rc
= next_entry(buf
, fp
, sizeof(u32
));
230 printk(KERN_ERR
"security: ebitmap: truncated map\n");
233 n
= kzalloc(sizeof(*n
), GFP_KERNEL
);
235 printk(KERN_ERR
"security: ebitmap: out of memory\n");
240 n
->startbit
= le32_to_cpu(buf
[0]);
242 if (n
->startbit
& (MAPSIZE
- 1)) {
243 printk(KERN_ERR
"security: ebitmap start bit (%d) is "
244 "not a multiple of the map size (%Zd)\n",
245 n
->startbit
, MAPSIZE
);
248 if (n
->startbit
> (e
->highbit
- MAPSIZE
)) {
249 printk(KERN_ERR
"security: ebitmap start bit (%d) is "
250 "beyond the end of the bitmap (%Zd)\n",
251 n
->startbit
, (e
->highbit
- MAPSIZE
));
254 rc
= next_entry(&map
, fp
, sizeof(u64
));
256 printk(KERN_ERR
"security: ebitmap: truncated map\n");
259 n
->map
= le64_to_cpu(map
);
262 printk(KERN_ERR
"security: ebitmap: null map in "
263 "ebitmap (startbit %d)\n", n
->startbit
);
267 if (n
->startbit
<= l
->startbit
) {
268 printk(KERN_ERR
"security: ebitmap: start "
269 "bit %d comes after start bit %d\n",
270 n
->startbit
, l
->startbit
);