[Ocfs2-tools-commits] mfasheh commits r858 - in trunk/libo2dlm: . include

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Apr 28 13:54:43 CDT 2005


Author: mfasheh
Signed-off-by: manish
Date: 2005-04-28 13:54:41 -0500 (Thu, 28 Apr 2005)
New Revision: 858

Modified:
   trunk/libo2dlm/include/o2dlm.h
   trunk/libo2dlm/o2dlm.c
Log:
* Use a hash table in libo2dlm to track lock resources

Signed-off-by: manish



Modified: trunk/libo2dlm/include/o2dlm.h
===================================================================
--- trunk/libo2dlm/include/o2dlm.h	2005-04-28 17:25:13 UTC (rev 857)
+++ trunk/libo2dlm/include/o2dlm.h	2005-04-28 18:54:41 UTC (rev 858)
@@ -62,7 +62,7 @@
 
 struct o2dlm_lock_res
 {
-	struct list_head      l_list;  /* to hang us off the locks list */
+	struct list_head      l_bucket; /* to hang us off the locks list */
 	char                  l_id[O2DLM_LOCK_ID_MAX_LEN]; /* 32 byte,
 							    * null
 							    * terminated
@@ -74,7 +74,8 @@
 
 struct o2dlm_ctxt
 {
-	struct list_head ct_locks;  /* the list of locks */
+	struct list_head *ct_hash;
+	unsigned int     ct_hash_size;
 	char             ct_domain_path[O2DLM_MAX_FULL_DOMAIN_PATH]; /* domain
 								      * dir */
 	char             ct_ctxt_lock_name[O2DLM_LOCK_ID_MAX_LEN];

Modified: trunk/libo2dlm/o2dlm.c
===================================================================
--- trunk/libo2dlm/o2dlm.c	2005-04-28 17:25:13 UTC (rev 857)
+++ trunk/libo2dlm/o2dlm.c	2005-04-28 18:54:41 UTC (rev 858)
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
+#include <assert.h>
 #include <inttypes.h>
 
 #include <sys/statfs.h>
@@ -64,6 +65,15 @@
 	return 0;
 }
 
+static void o2dlm_free_ctxt(struct o2dlm_ctxt *ctxt)
+{
+	if (ctxt->ct_hash)
+		free(ctxt->ct_hash);
+	free(ctxt);
+}
+
+#define O2DLM_DEFAULT_HASH_SIZE 4096
+
 static errcode_t o2dlm_alloc_ctxt(const char *mnt_path,
 				  const char *dirname,
 				  struct o2dlm_ctxt **dlm_ctxt)
@@ -71,7 +81,7 @@
 	errcode_t err;
 	struct o2dlm_ctxt *ctxt;
 	int64_t rand;
-	int len;
+	int len, i;
 
 	err = o2dlm_generate_random_value(&rand);
 	if (err)
@@ -81,6 +91,17 @@
 	if (!ctxt)
 		return O2DLM_ET_NO_MEMORY;
 
+	ctxt->ct_hash_size = O2DLM_DEFAULT_HASH_SIZE;
+
+	ctxt->ct_hash = calloc(ctxt->ct_hash_size, sizeof(struct list_head));
+	if (!ctxt->ct_hash) {
+		err = O2DLM_ET_NO_MEMORY;
+		goto exit_and_free;
+	}
+
+	for(i = 0; i < ctxt->ct_hash_size; i++)
+		INIT_LIST_HEAD(&ctxt->ct_hash[i]);
+
 	len = snprintf(ctxt->ct_ctxt_lock_name, O2DLM_LOCK_ID_MAX_LEN,
 		       ".%016"PRIx64, rand);
 	if (len == O2DLM_LOCK_ID_MAX_LEN) {
@@ -91,8 +112,6 @@
 		goto exit_and_free;
 	}
 
-	INIT_LIST_HEAD(&ctxt->ct_locks);
-
 	len = snprintf(ctxt->ct_domain_path, PATH_MAX + 1, "%s/%s",
 		       mnt_path, dirname);
 	if (len == (PATH_MAX + 1)) {
@@ -107,15 +126,10 @@
 	err = 0;
 exit_and_free:
 	if (err)
-		free(ctxt);
+		o2dlm_free_ctxt(ctxt);
 	return err;
 }
 
-static void o2dlm_free_ctxt(struct o2dlm_ctxt *ctxt)
-{
-	free(ctxt);
-}
-
 static errcode_t o2dlm_check_user_dlmfs(const char *dlmfs_path)
 {
 	struct statfs statfs_buf;
@@ -270,20 +284,68 @@
 	return 0;
 }
 
+/* 
+ * Most of this hash function taken from dcache.h. It has the
+ * following copyright line at the top:
+ *	
+ * (C) Copyright 1997 Thomas Schoebel-Theuer,
+ * with heavy changes by Linus Torvalds
+ */
+static inline unsigned long
+partial_name_hash(unsigned long c, unsigned long prevhash)
+{
+	return (prevhash + (c << 4) + (c >> 4)) * 11;
+}
+
+static inline unsigned int o2dlm_hash_lockname(struct o2dlm_ctxt *ctxt,
+					       const char *name)
+{
+	unsigned long hash = 0;
+	unsigned int bucket;
+
+	while(*name)
+		hash = partial_name_hash(*name++, hash);
+
+	bucket = (unsigned int) hash % ctxt->ct_hash_size;
+
+	assert(bucket < ctxt->ct_hash_size);
+
+	return bucket;
+}
+
 static struct o2dlm_lock_res *o2dlm_find_lock_res(struct o2dlm_ctxt *ctxt,
 						  const char *lockid)
 {
 	struct o2dlm_lock_res *lockres;
 	struct list_head *p;
+	unsigned int bucket;
 
-	list_for_each(p, &ctxt->ct_locks) {
-		lockres = list_entry(p, struct o2dlm_lock_res, l_list);
+	bucket = o2dlm_hash_lockname(ctxt, lockid);
+
+	list_for_each(p, &ctxt->ct_hash[bucket]) {
+		lockres = list_entry(p, struct o2dlm_lock_res, l_bucket);
 		if (!strcmp(lockid, lockres->l_id))
 			return lockres;
 	}
 	return NULL;
 }
 
+static void o2dlm_insert_lock_res(struct o2dlm_ctxt *ctxt,
+				  struct o2dlm_lock_res *lockres)
+{
+	unsigned int bucket;
+
+	bucket = o2dlm_hash_lockname(ctxt, lockres->l_id);
+
+	list_add_tail(&lockres->l_bucket, &ctxt->ct_hash[bucket]);
+}
+
+static inline void o2dlm_remove_lock_res(struct o2dlm_lock_res *lockres)
+{
+	list_del(&lockres->l_bucket);
+	INIT_LIST_HEAD(&lockres->l_bucket);
+}
+
 static int o2dlm_translate_lock_flags(enum o2dlm_lock_level level,
 				      int lockflags)
 {
@@ -316,7 +378,7 @@
 	if (lockres) {
 		memset(lockres, 0, sizeof(*lockres));
 
-		INIT_LIST_HEAD(&lockres->l_list);
+		INIT_LIST_HEAD(&lockres->l_bucket);
 
 		strncpy(lockres->l_id, id, O2DLM_LOCK_ID_MAX_LEN);
 
@@ -381,7 +443,7 @@
 	lockres->l_flags = lockflags;
 	lockres->l_fd = fd;
 
-	list_add_tail(&lockres->l_list, &ctxt->ct_locks);
+	o2dlm_insert_lock_res(ctxt, lockres);
 
 	free(path);
 
@@ -404,7 +466,7 @@
 }
 
 static errcode_t o2dlm_unlock_lock_res(struct o2dlm_ctxt *ctxt,
-				      struct o2dlm_lock_res *lockres)
+				       struct o2dlm_lock_res *lockres)
 {
 	int ret, len = PATH_MAX + 1;
 	char *path;
@@ -449,7 +511,7 @@
 	if (!lockres)
 		return O2DLM_ET_UNKNOWN_LOCK;
 
-	list_del(&lockres->l_list);
+	o2dlm_remove_lock_res(lockres);
 
 	ret = o2dlm_unlock_lock_res(ctxt, lockres);
 
@@ -575,22 +637,28 @@
 
 errcode_t o2dlm_destroy(struct o2dlm_ctxt *ctxt)
 {
-	int ret;
+	int ret, i;
 	int error = 0;
 	struct o2dlm_lock_res *lockres;
-        struct list_head *p, *n;
+        struct list_head *p, *n, *bucket;
 
 	if (!ctxt)
 		return O2DLM_ET_INVALID_ARGS;
 
-	list_for_each_safe(p, n, &ctxt->ct_locks) {
-		lockres = list_entry(p, struct o2dlm_lock_res, l_list);
-		list_del(&lockres->l_list);
+	for(i = 0; i < ctxt->ct_hash_size; i++) {
+		bucket = &ctxt->ct_hash[i];
 
-		ret = o2dlm_unlock_lock_res(ctxt, lockres);
-		if (ret && (ret != O2DLM_ET_BUSY_LOCK))
-			error = O2DLM_ET_FAILED_UNLOCKS;
-		free(lockres);
+		list_for_each_safe(p, n, bucket) {
+			lockres = list_entry(p, struct o2dlm_lock_res,
+					     l_bucket);
+
+			o2dlm_remove_lock_res(lockres);
+
+			ret = o2dlm_unlock_lock_res(ctxt, lockres);
+			if (ret && (ret != O2DLM_ET_BUSY_LOCK))
+				error = O2DLM_ET_FAILED_UNLOCKS;
+			free(lockres);
+		}
 	}
 	if (error)
 		goto free_and_exit;



More information about the Ocfs2-tools-commits mailing list