#include <linux/lustre_handles.h>
static spinlock_t handle_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t random_lock = SPIN_LOCK_UNLOCKED;
+static __u64 handle_base;
+#define HANDLE_INCR 7
static struct list_head *handle_hash = NULL;
static int handle_count = 0;
LASSERT(h != NULL);
LASSERT(list_empty(&h->h_link));
- /* My hypothesis is that get_random_bytes, if called from two threads at
- * the same time, will return the same bytes. -phil */
- spin_lock(&random_lock);
- get_random_bytes(&h->h_cookie, sizeof(h->h_cookie));
- spin_unlock(&random_lock);
+ spin_lock(&handle_lock);
+ h->h_cookie = handle_base;
+ handle_base += HANDLE_INCR;
+ spin_unlock(&handle_lock);
h->h_addref = cb;
-
bucket = handle_hash + (h->h_cookie & HANDLE_HASH_MASK);
-
CDEBUG(D_INFO, "adding object %p with handle "LPX64" to hash\n",
h, h->h_cookie);
static void class_handle_unhash_nolock(struct portals_handle *h)
{
- LASSERT(!list_empty(&h->h_link));
+ if (list_empty(&h->h_link)) {
+ CERROR("removing an already-removed handle ("LPX64")\n",
+ h->h_cookie);
+ return;
+ }
CDEBUG(D_INFO, "removing object %p with handle "LPX64" from hash\n",
h, h->h_cookie);
LASSERT(handle_hash != NULL);
- spin_lock(&handle_lock);
bucket = handle_hash + (cookie & HANDLE_HASH_MASK);
+ spin_lock(&handle_lock);
list_for_each(tmp, bucket) {
struct portals_handle *h;
h = list_entry(tmp, struct portals_handle, h_link);
bucket--)
INIT_LIST_HEAD(bucket);
+ get_random_bytes(&handle_base, sizeof(handle_base));
+ LASSERT(handle_base != 0ULL);
+
return 0;
}
struct portals_handle *h;
h = list_entry(tmp, struct portals_handle, h_link);
- CERROR("forcing cleanup for handle "LPX64"\n",
- h->h_cookie);
+ CERROR("force clean handle "LPX64" addr %p addref %p\n",
+ h->h_cookie, h, h->h_addref);
class_handle_unhash_nolock(h);
}