X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Flustre_handles.c;h=061090a8b7f8919e492c8f00fca4e49e5bd0d976;hb=c438fba7f068b0713d96dce1f0183ec6da7ab000;hp=4161b2dabfd728443d3df6e6e75057e8ded3b59c;hpb=195c8ac1415f1152332273d4465ff436bfbf63e4;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/lustre_handles.c b/lustre/obdclass/lustre_handles.c index 4161b2d..061090a 100644 --- a/lustre/obdclass/lustre_handles.c +++ b/lustre/obdclass/lustre_handles.c @@ -36,6 +36,8 @@ #define DEBUG_SUBSYSTEM S_CLASS +#include + #include #include #include @@ -47,7 +49,7 @@ static DEFINE_SPINLOCK(handle_base_lock); static struct handle_bucket { spinlock_t lock; - struct list_head head; + struct hlist_head head; } *handle_hash; #define HANDLE_HASH_SIZE (1 << 16) @@ -57,15 +59,14 @@ static struct handle_bucket { * Generate a unique 64bit cookie (hash) for a handle and insert it into * global (per-node) hash-table. */ -void class_handle_hash(struct portals_handle *h, - struct portals_handle_ops *ops) +void class_handle_hash(struct portals_handle *h, const char *owner) { struct handle_bucket *bucket; ENTRY; LASSERT(h != NULL); - LASSERT(list_empty(&h->h_link)); + LASSERT(hlist_unhashed(&h->h_link)); /* * This is fast, but simplistic cookie generation algorithm, it will @@ -86,13 +87,11 @@ void class_handle_hash(struct portals_handle *h, h->h_cookie = handle_base; spin_unlock(&handle_base_lock); - h->h_ops = ops; - spin_lock_init(&h->h_lock); + h->h_owner = owner; bucket = &handle_hash[h->h_cookie & HANDLE_HASH_MASK]; spin_lock(&bucket->lock); - list_add_rcu(&h->h_link, &bucket->head); - h->h_in = 1; + hlist_add_head_rcu(&h->h_link, &bucket->head); spin_unlock(&bucket->lock); CDEBUG(D_INFO, "added object %p with handle %#llx to hash\n", @@ -103,7 +102,7 @@ EXPORT_SYMBOL(class_handle_hash); static void class_handle_unhash_nolock(struct portals_handle *h) { - if (list_empty(&h->h_link)) { + if (hlist_unhashed(&h->h_link)) { CERROR("removing an already-removed handle (%#llx)\n", h->h_cookie); return; @@ -112,14 +111,7 @@ static void class_handle_unhash_nolock(struct portals_handle *h) CDEBUG(D_INFO, "removing object %p with handle %#llx from hash\n", h, h->h_cookie); - spin_lock(&h->h_lock); - if (h->h_in == 0) { - spin_unlock(&h->h_lock); - return; - } - h->h_in = 0; - spin_unlock(&h->h_lock); - list_del_rcu(&h->h_link); + hlist_del_init_rcu(&h->h_link); } void class_handle_unhash(struct portals_handle *h) @@ -133,23 +125,7 @@ void class_handle_unhash(struct portals_handle *h) } EXPORT_SYMBOL(class_handle_unhash); -void class_handle_hash_back(struct portals_handle *h) -{ - struct handle_bucket *bucket; - ENTRY; - - bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK); - - spin_lock(&bucket->lock); - list_add_rcu(&h->h_link, &bucket->head); - h->h_in = 1; - spin_unlock(&bucket->lock); - - EXIT; -} -EXPORT_SYMBOL(class_handle_hash_back); - -void *class_handle2object(__u64 cookie, const void *owner) +void *class_handle2object(u64 cookie, const char *owner) { struct handle_bucket *bucket; struct portals_handle *h; @@ -166,16 +142,16 @@ void *class_handle2object(__u64 cookie, const void *owner) bucket = handle_hash + (cookie & HANDLE_HASH_MASK); rcu_read_lock(); - list_for_each_entry_rcu(h, &bucket->head, h_link) { + hlist_for_each_entry_rcu(h, &bucket->head, h_link) { if (h->h_cookie != cookie || h->h_owner != owner) continue; - spin_lock(&h->h_lock); - if (likely(h->h_in != 0)) { - h->h_ops->hop_addref(h); + if (refcount_inc_not_zero(&h->h_ref)) { + CDEBUG(D_INFO, "GET %s %p refcount=%d\n", + h->h_owner, h, + refcount_read(&h->h_ref)); retval = h; } - spin_unlock(&h->h_lock); break; } rcu_read_unlock(); @@ -184,45 +160,23 @@ void *class_handle2object(__u64 cookie, const void *owner) } EXPORT_SYMBOL(class_handle2object); -void class_handle_free_cb(struct rcu_head *rcu) -{ - struct portals_handle *h; - void *ptr; - - h = container_of(rcu, struct portals_handle, h_rcu); - ptr = (void *)(unsigned long)h->h_cookie; - - if (h->h_ops->hop_free != NULL) - h->h_ops->hop_free(ptr, h->h_size); - else - OBD_FREE(ptr, h->h_size); -} -EXPORT_SYMBOL(class_handle_free_cb); - int class_handle_init(void) { struct handle_bucket *bucket; - struct timespec64 ts; - int seed[2]; LASSERT(handle_hash == NULL); - OBD_ALLOC_LARGE(handle_hash, sizeof(*bucket) * HANDLE_HASH_SIZE); + OBD_ALLOC_PTR_ARRAY_LARGE(handle_hash, HANDLE_HASH_SIZE); if (handle_hash == NULL) return -ENOMEM; for (bucket = handle_hash + HANDLE_HASH_SIZE - 1; bucket >= handle_hash; bucket--) { - INIT_LIST_HEAD(&bucket->head); + INIT_HLIST_HEAD(&bucket->head); spin_lock_init(&bucket->lock); } - /** bug 21430: add randomness to the initial base */ - cfs_get_random_bytes(seed, sizeof(seed)); - ktime_get_ts64(&ts); - cfs_srand(ts.tv_sec ^ seed[0], ts.tv_nsec ^ seed[1]); - - cfs_get_random_bytes(&handle_base, sizeof(handle_base)); + get_random_bytes(&handle_base, sizeof(handle_base)); LASSERT(handle_base != 0ULL); return 0; @@ -237,9 +191,9 @@ static int cleanup_all_handles(void) struct portals_handle *h; spin_lock(&handle_hash[i].lock); - list_for_each_entry_rcu(h, &(handle_hash[i].head), h_link) { - CERROR("force clean handle %#llx addr %p ops %p\n", - h->h_cookie, h, h->h_ops); + hlist_for_each_entry_rcu(h, &handle_hash[i].head, h_link) { + CERROR("force clean handle %#llx addr %p owner %p\n", + h->h_cookie, h, h->h_owner); class_handle_unhash_nolock(h); rc++; @@ -258,7 +212,7 @@ void class_handle_cleanup(void) count = cleanup_all_handles(); - OBD_FREE_LARGE(handle_hash, sizeof(*handle_hash) * HANDLE_HASH_SIZE); + OBD_FREE_PTR_ARRAY_LARGE(handle_hash, HANDLE_HASH_SIZE); handle_hash = NULL; if (count != 0)