static int calipso_cache_add(const unsigned char *calipso_ptr,
			     const struct netlbl_lsm_secattr *secattr)
{
	int ret_val = -EPERM;
	u32 bkt;
	struct calipso_map_cache_entry *entry = NULL;
	struct calipso_map_cache_entry *old_entry = NULL;
	u32 calipso_ptr_len;

	if (!calipso_cache_enabled || calipso_cache_bucketsize <= 0)
		return 0;

	calipso_ptr_len = calipso_ptr[1];

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;
	entry->key = kmemdup(calipso_ptr + 2, calipso_ptr_len, GFP_ATOMIC);
	if (!entry->key) {
		ret_val = -ENOMEM;
		goto cache_add_failure;
	}
	entry->key_len = calipso_ptr_len;
	entry->hash = calipso_map_cache_hash(calipso_ptr, calipso_ptr_len);
	refcount_inc(&secattr->cache->refcount);
	entry->lsm_data = secattr->cache;

	bkt = entry->hash & (CALIPSO_CACHE_BUCKETS - 1);
	spin_lock_bh(&calipso_cache[bkt].lock);
	if (calipso_cache[bkt].size < calipso_cache_bucketsize) {
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache[bkt].size += 1;
	} else {
		old_entry = list_entry(calipso_cache[bkt].list.prev,
				       struct calipso_map_cache_entry, list);
		list_del(&old_entry->list);
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache_entry_free(old_entry);
	}
	spin_unlock_bh(&calipso_cache[bkt].lock);

	return 0;

cache_add_failure:
	if (entry)
		calipso_cache_entry_free(entry);
	return ret_val;
}
static int calipso_cache_add(const unsigned char *calipso_ptr,
			     const struct netlbl_lsm_secattr *secattr)
{
	int ret_val = -EPERM;
	u32 bkt;
	struct calipso_map_cache_entry *entry = NULL;
	struct calipso_map_cache_entry *old_entry = NULL;
	u32 calipso_ptr_len;

	if (!calipso_cache_enabled || calipso_cache_bucketsize <= 0)
		return 0;

	calipso_ptr_len = calipso_ptr[1];

	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;
	entry->key = kmemdup(calipso_ptr + 2, calipso_ptr_len, GFP_ATOMIC);
	if (!entry->key) {
		ret_val = -ENOMEM;
		goto cache_add_failure;
	}
	entry->key_len = calipso_ptr_len;
	entry->hash = calipso_map_cache_hash(calipso_ptr, calipso_ptr_len);
	refcount_inc(&secattr->cache->refcount);
	entry->lsm_data = secattr->cache;

	bkt = entry->hash & (CALIPSO_CACHE_BUCKETS - 1);
	spin_lock_bh(&calipso_cache[bkt].lock);
	if (calipso_cache[bkt].size < calipso_cache_bucketsize) {
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache[bkt].size += 1;
	} else {
		old_entry = list_entry(calipso_cache[bkt].list.prev,
				       struct calipso_map_cache_entry, list);
		list_del(&old_entry->list);
		list_add(&entry->list, &calipso_cache[bkt].list);
		calipso_cache_entry_free(old_entry);
	}
	spin_unlock_bh(&calipso_cache[bkt].lock);

	return 0;

cache_add_failure:
	if (entry)
		calipso_cache_entry_free(entry);
	return ret_val;
}