} u;
};
-#define UC_CACHE_HASH_SIZE (128)
-#define UC_CACHE_HASH_INDEX(id) ((id) & (UC_CACHE_HASH_SIZE - 1))
+#define UC_CACHE_HASH_INDEX(id, size) ((id) & ((size) - 1))
#define UC_CACHE_UPCALL_MAXPATH (1024UL)
struct upcall_cache;
};
struct upcall_cache {
- struct list_head uc_hashtable[UC_CACHE_HASH_SIZE];
+ struct list_head *uc_hashtable;
+ int uc_hashsize;
spinlock_t uc_lock;
struct rw_semaphore uc_upcall_rwsem;
void upcall_cache_flush_one(struct upcall_cache *cache, __u64 key, void *args);
struct upcall_cache *upcall_cache_init(const char *name, const char *upcall,
- struct upcall_cache_ops *ops);
+ int hashsz, struct upcall_cache_ops *ops);
void upcall_cache_cleanup(struct upcall_cache *cache);
/** @} ucache */
LASSERT(cache);
- head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key)];
+ head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key,
+ cache->uc_hashsize)];
find_again:
found = 0;
spin_lock(&cache->uc_lock);
LASSERT(cache);
- head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key)];
+ head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key,
+ cache->uc_hashsize)];
spin_lock(&cache->uc_lock);
list_for_each_entry(entry, head, ue_hash) {
ENTRY;
spin_lock(&cache->uc_lock);
- for (i = 0; i < UC_CACHE_HASH_SIZE; i++) {
+ for (i = 0; i < cache->uc_hashsize; i++) {
list_for_each_entry_safe(entry, next,
&cache->uc_hashtable[i], ue_hash) {
if (!force && atomic_read(&entry->ue_refcount)) {
int found = 0;
ENTRY;
- head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key)];
+ head = &cache->uc_hashtable[UC_CACHE_HASH_INDEX(key,
+ cache->uc_hashsize)];
spin_lock(&cache->uc_lock);
list_for_each_entry(entry, head, ue_hash) {
EXPORT_SYMBOL(upcall_cache_flush_one);
struct upcall_cache *upcall_cache_init(const char *name, const char *upcall,
- struct upcall_cache_ops *ops)
+ int hashsz, struct upcall_cache_ops *ops)
{
struct upcall_cache *cache;
int i;
spin_lock_init(&cache->uc_lock);
init_rwsem(&cache->uc_upcall_rwsem);
- for (i = 0; i < UC_CACHE_HASH_SIZE; i++)
+ cache->uc_hashsize = hashsz;
+ LIBCFS_ALLOC(cache->uc_hashtable,
+ sizeof(*cache->uc_hashtable) * cache->uc_hashsize);
+ if (!cache->uc_hashtable)
+ RETURN(ERR_PTR(-ENOMEM));
+ for (i = 0; i < cache->uc_hashsize; i++)
INIT_LIST_HEAD(&cache->uc_hashtable[i]);
strlcpy(cache->uc_name, name, sizeof(cache->uc_name));
/* upcall pathname proc tunable */
if (!cache)
return;
upcall_cache_flush_all(cache);
+ LIBCFS_FREE(cache->uc_hashtable,
+ sizeof(*cache->uc_hashtable) * cache->uc_hashsize);
LIBCFS_FREE(cache, sizeof(*cache));
}
EXPORT_SYMBOL(upcall_cache_cleanup);