diff options
author | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 12:17:53 -0700 |
---|---|---|
committer | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 15:44:42 -0700 |
commit | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch) | |
tree | 1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/security/selinux/ss/hashtab.c | |
parent | 98260f3884f4a202f9ca5eabed40b1354c489b29 (diff) |
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base.
It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and
the base is:
commit 0917f823c59692d751951bf5ea699a2d1e2f26a2
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Sat Jul 25 12:13:34 2015 +0200
Prepare v4.1.3-rt3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
We lose all the git history this way and it's not good. We
should apply another opnfv project repo in future.
Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/security/selinux/ss/hashtab.c')
-rw-r--r-- | kernel/security/selinux/ss/hashtab.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/kernel/security/selinux/ss/hashtab.c b/kernel/security/selinux/ss/hashtab.c new file mode 100644 index 000000000..2cc496149 --- /dev/null +++ b/kernel/security/selinux/ss/hashtab.c @@ -0,0 +1,168 @@ +/* + * Implementation of the hash table type. + * + * Author : Stephen Smalley, <sds@epoch.ncsc.mil> + */ +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include "hashtab.h" + +struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), + int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), + u32 size) +{ + struct hashtab *p; + u32 i; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) + return p; + + p->size = size; + p->nel = 0; + p->hash_value = hash_value; + p->keycmp = keycmp; + p->htable = kmalloc(sizeof(*(p->htable)) * size, GFP_KERNEL); + if (p->htable == NULL) { + kfree(p); + return NULL; + } + + for (i = 0; i < size; i++) + p->htable[i] = NULL; + + return p; +} + +int hashtab_insert(struct hashtab *h, void *key, void *datum) +{ + u32 hvalue; + struct hashtab_node *prev, *cur, *newnode; + + cond_resched(); + + if (!h || h->nel == HASHTAB_MAX_NODES) + return -EINVAL; + + hvalue = h->hash_value(h, key); + prev = NULL; + cur = h->htable[hvalue]; + while (cur && h->keycmp(h, key, cur->key) > 0) { + prev = cur; + cur = cur->next; + } + + if (cur && (h->keycmp(h, key, cur->key) == 0)) + return -EEXIST; + + newnode = kzalloc(sizeof(*newnode), GFP_KERNEL); + if (newnode == NULL) + return -ENOMEM; + newnode->key = key; + newnode->datum = datum; + if (prev) { + newnode->next = prev->next; + prev->next = newnode; + } else { + newnode->next = h->htable[hvalue]; + h->htable[hvalue] = newnode; + } + + h->nel++; + return 0; +} + +void *hashtab_search(struct hashtab *h, const void *key) +{ + u32 hvalue; + struct hashtab_node *cur; + + if (!h) + return NULL; + + hvalue = h->hash_value(h, key); + cur = h->htable[hvalue]; + while (cur && h->keycmp(h, key, cur->key) > 0) + cur = cur->next; + + if (cur == NULL || (h->keycmp(h, key, cur->key) != 0)) + return NULL; + + return cur->datum; +} + +void hashtab_destroy(struct hashtab *h) +{ + u32 i; + struct hashtab_node *cur, *temp; + + if (!h) + return; + + for (i = 0; i < h->size; i++) { + cur = h->htable[i]; + while (cur) { + temp = cur; + cur = cur->next; + kfree(temp); + } + h->htable[i] = NULL; + } + + kfree(h->htable); + h->htable = NULL; + + kfree(h); +} + +int hashtab_map(struct hashtab *h, + int (*apply)(void *k, void *d, void *args), + void *args) +{ + u32 i; + int ret; + struct hashtab_node *cur; + + if (!h) + return 0; + + for (i = 0; i < h->size; i++) { + cur = h->htable[i]; + while (cur) { + ret = apply(cur->key, cur->datum, args); + if (ret) + return ret; + cur = cur->next; + } + } + return 0; +} + + +void hashtab_stat(struct hashtab *h, struct hashtab_info *info) +{ + u32 i, chain_len, slots_used, max_chain_len; + struct hashtab_node *cur; + + slots_used = 0; + max_chain_len = 0; + for (slots_used = max_chain_len = i = 0; i < h->size; i++) { + cur = h->htable[i]; + if (cur) { + slots_used++; + chain_len = 0; + while (cur) { + chain_len++; + cur = cur->next; + } + + if (chain_len > max_chain_len) + max_chain_len = chain_len; + } + } + + info->slots_used = slots_used; + info->max_chain_len = max_chain_len; +} |