diff options
Diffstat (limited to 'security/selinux/ss/ebitmap.h')
-rw-r--r-- | security/selinux/ss/ebitmap.h | 87 |
1 files changed, 66 insertions, 21 deletions
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index 1270e34b61c1..e38a327dd703 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h | |||
@@ -16,14 +16,16 @@ | |||
16 | 16 | ||
17 | #include <net/netlabel.h> | 17 | #include <net/netlabel.h> |
18 | 18 | ||
19 | #define MAPTYPE u64 /* portion of bitmap in each node */ | 19 | #define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \ |
20 | #define MAPSIZE (sizeof(MAPTYPE) * 8) /* number of bits in node bitmap */ | 20 | / sizeof(unsigned long)) |
21 | #define MAPBIT 1ULL /* a bit in the node bitmap */ | 21 | #define EBITMAP_UNIT_SIZE BITS_PER_LONG |
22 | #define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) | ||
23 | #define EBITMAP_BIT 1ULL | ||
22 | 24 | ||
23 | struct ebitmap_node { | 25 | struct ebitmap_node { |
24 | u32 startbit; /* starting position in the total bitmap */ | ||
25 | MAPTYPE map; /* this node's portion of the bitmap */ | ||
26 | struct ebitmap_node *next; | 26 | struct ebitmap_node *next; |
27 | unsigned long maps[EBITMAP_UNIT_NUMS]; | ||
28 | u32 startbit; | ||
27 | }; | 29 | }; |
28 | 30 | ||
29 | struct ebitmap { | 31 | struct ebitmap { |
@@ -34,11 +36,17 @@ struct ebitmap { | |||
34 | #define ebitmap_length(e) ((e)->highbit) | 36 | #define ebitmap_length(e) ((e)->highbit) |
35 | #define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) | 37 | #define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0) |
36 | 38 | ||
37 | static inline unsigned int ebitmap_start(struct ebitmap *e, | 39 | static inline unsigned int ebitmap_start_positive(struct ebitmap *e, |
38 | struct ebitmap_node **n) | 40 | struct ebitmap_node **n) |
39 | { | 41 | { |
40 | *n = e->node; | 42 | unsigned int ofs; |
41 | return ebitmap_startbit(e); | 43 | |
44 | for (*n = e->node; *n; *n = (*n)->next) { | ||
45 | ofs = find_first_bit((*n)->maps, EBITMAP_SIZE); | ||
46 | if (ofs < EBITMAP_SIZE) | ||
47 | return (*n)->startbit + ofs; | ||
48 | } | ||
49 | return ebitmap_length(e); | ||
42 | } | 50 | } |
43 | 51 | ||
44 | static inline void ebitmap_init(struct ebitmap *e) | 52 | static inline void ebitmap_init(struct ebitmap *e) |
@@ -46,28 +54,65 @@ static inline void ebitmap_init(struct ebitmap *e) | |||
46 | memset(e, 0, sizeof(*e)); | 54 | memset(e, 0, sizeof(*e)); |
47 | } | 55 | } |
48 | 56 | ||
49 | static inline unsigned int ebitmap_next(struct ebitmap_node **n, | 57 | static inline unsigned int ebitmap_next_positive(struct ebitmap *e, |
50 | unsigned int bit) | 58 | struct ebitmap_node **n, |
59 | unsigned int bit) | ||
51 | { | 60 | { |
52 | if ((bit == ((*n)->startbit + MAPSIZE - 1)) && | 61 | unsigned int ofs; |
53 | (*n)->next) { | 62 | |
54 | *n = (*n)->next; | 63 | ofs = find_next_bit((*n)->maps, EBITMAP_SIZE, bit - (*n)->startbit + 1); |
55 | return (*n)->startbit; | 64 | if (ofs < EBITMAP_SIZE) |
56 | } | 65 | return ofs + (*n)->startbit; |
57 | 66 | ||
58 | return (bit+1); | 67 | for (*n = (*n)->next; *n; *n = (*n)->next) { |
68 | ofs = find_first_bit((*n)->maps, EBITMAP_SIZE); | ||
69 | if (ofs < EBITMAP_SIZE) | ||
70 | return ofs + (*n)->startbit; | ||
71 | } | ||
72 | return ebitmap_length(e); | ||
59 | } | 73 | } |
60 | 74 | ||
61 | static inline int ebitmap_node_get_bit(struct ebitmap_node * n, | 75 | #define EBITMAP_NODE_INDEX(node, bit) \ |
76 | (((bit) - (node)->startbit) / EBITMAP_UNIT_SIZE) | ||
77 | #define EBITMAP_NODE_OFFSET(node, bit) \ | ||
78 | (((bit) - (node)->startbit) % EBITMAP_UNIT_SIZE) | ||
79 | |||
80 | static inline int ebitmap_node_get_bit(struct ebitmap_node *n, | ||
62 | unsigned int bit) | 81 | unsigned int bit) |
63 | { | 82 | { |
64 | if (n->map & (MAPBIT << (bit - n->startbit))) | 83 | unsigned int index = EBITMAP_NODE_INDEX(n, bit); |
84 | unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); | ||
85 | |||
86 | BUG_ON(index >= EBITMAP_UNIT_NUMS); | ||
87 | if ((n->maps[index] & (EBITMAP_BIT << ofs))) | ||
65 | return 1; | 88 | return 1; |
66 | return 0; | 89 | return 0; |
67 | } | 90 | } |
68 | 91 | ||
69 | #define ebitmap_for_each_bit(e, n, bit) \ | 92 | static inline void ebitmap_node_set_bit(struct ebitmap_node *n, |
70 | for (bit = ebitmap_start(e, &n); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \ | 93 | unsigned int bit) |
94 | { | ||
95 | unsigned int index = EBITMAP_NODE_INDEX(n, bit); | ||
96 | unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); | ||
97 | |||
98 | BUG_ON(index >= EBITMAP_UNIT_NUMS); | ||
99 | n->maps[index] |= (EBITMAP_BIT << ofs); | ||
100 | } | ||
101 | |||
102 | static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, | ||
103 | unsigned int bit) | ||
104 | { | ||
105 | unsigned int index = EBITMAP_NODE_INDEX(n, bit); | ||
106 | unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit); | ||
107 | |||
108 | BUG_ON(index >= EBITMAP_UNIT_NUMS); | ||
109 | n->maps[index] &= ~(EBITMAP_BIT << ofs); | ||
110 | } | ||
111 | |||
112 | #define ebitmap_for_each_positive_bit(e, n, bit) \ | ||
113 | for (bit = ebitmap_start_positive(e, &n); \ | ||
114 | bit < ebitmap_length(e); \ | ||
115 | bit = ebitmap_next_positive(e, &n, bit)) \ | ||
71 | 116 | ||
72 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); | 117 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); |
73 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); | 118 | int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); |