summaryrefslogtreecommitdiff
path: root/security/selinux/ss/hashtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/hashtab.c')
-rw-r--r--security/selinux/ss/hashtab.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index 3fb8f9026e9b..1382eb3bfde1 100644
--- a/security/selinux/ss/hashtab.c
+++ b/security/selinux/ss/hashtab.c
@@ -2,8 +2,9 @@
/*
* Implementation of the hash table type.
*
- * Author : Stephen Smalley, <sds@tycho.nsa.gov>
+ * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
*/
+
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -39,7 +40,8 @@ int hashtab_init(struct hashtab *h, u32 nel_hint)
h->htable = NULL;
if (size) {
- h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL);
+ h->htable = kcalloc(size, sizeof(*h->htable),
+ GFP_KERNEL | __GFP_NOWARN);
if (!h->htable)
return -ENOMEM;
h->size = size;
@@ -47,8 +49,8 @@ int hashtab_init(struct hashtab *h, u32 nel_hint)
return 0;
}
-int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
- void *key, void *datum)
+int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, void *key,
+ void *datum)
{
struct hashtab_node *newnode;
@@ -83,8 +85,7 @@ void hashtab_destroy(struct hashtab *h)
h->htable = NULL;
}
-int hashtab_map(struct hashtab *h,
- int (*apply)(void *k, void *d, void *args),
+int hashtab_map(struct hashtab *h, int (*apply)(void *k, void *d, void *args),
void *args)
{
u32 i;
@@ -103,14 +104,16 @@ int hashtab_map(struct hashtab *h,
return 0;
}
-
+#ifdef CONFIG_SECURITY_SELINUX_DEBUG
void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
{
u32 i, chain_len, slots_used, max_chain_len;
+ u64 chain2_len_sum;
struct hashtab_node *cur;
slots_used = 0;
max_chain_len = 0;
+ chain2_len_sum = 0;
for (i = 0; i < h->size; i++) {
cur = h->htable[i];
if (cur) {
@@ -123,21 +126,26 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info)
if (chain_len > max_chain_len)
max_chain_len = chain_len;
+
+ chain2_len_sum += (u64)chain_len * chain_len;
}
}
info->slots_used = slots_used;
info->max_chain_len = max_chain_len;
+ info->chain2_len_sum = chain2_len_sum;
}
+#endif /* CONFIG_SECURITY_SELINUX_DEBUG */
-int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
- int (*copy)(struct hashtab_node *new,
- struct hashtab_node *orig, void *args),
- int (*destroy)(void *k, void *d, void *args),
- void *args)
+int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig,
+ int (*copy)(struct hashtab_node *new,
+ const struct hashtab_node *orig, void *args),
+ int (*destroy)(void *k, void *d, void *args), void *args)
{
+ const struct hashtab_node *orig_cur;
struct hashtab_node *cur, *tmp, *tail;
- int i, rc;
+ u32 i;
+ int rc;
memset(new, 0, sizeof(*new));
@@ -149,12 +157,13 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
for (i = 0; i < orig->size; i++) {
tail = NULL;
- for (cur = orig->htable[i]; cur; cur = cur->next) {
+ for (orig_cur = orig->htable[i]; orig_cur;
+ orig_cur = orig_cur->next) {
tmp = kmem_cache_zalloc(hashtab_node_cachep,
GFP_KERNEL);
if (!tmp)
goto error;
- rc = copy(tmp, cur, args);
+ rc = copy(tmp, orig_cur, args);
if (rc) {
kmem_cache_free(hashtab_node_cachep, tmp);
goto error;
@@ -171,7 +180,7 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
return 0;
- error:
+error:
for (i = 0; i < new->size; i++) {
for (cur = new->htable[i]; cur; cur = tmp) {
tmp = cur->next;
@@ -186,7 +195,5 @@ int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
void __init hashtab_cache_init(void)
{
- hashtab_node_cachep = kmem_cache_create("hashtab_node",
- sizeof(struct hashtab_node),
- 0, SLAB_PANIC, NULL);
+ hashtab_node_cachep = KMEM_CACHE(hashtab_node, SLAB_PANIC);
}