[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ogfs-dev]Patch for integrating OpenDLM into OpenGFS



Hi, folks
Following is the patch support OpenDLM (with HOWTO and design doc).
Please give me your feedback :)

BTW, I will check all codes into cvs if there is not big problem in it.

Thanks!

Best Regards,
Stan
-- 
Opinions expressed are those of the author and do not represent Intel
Corporation
"gpg --recv-keys --keyserver wwwkeys.pgp.net E1390A7F"
{E1390A7F:3AD1 1B0C 2019 E183 0CFF  55E8 369A 8B75 E139 0A7F}

diff -Naur opengfs/configure.ac opengfs-opendlm/configure.ac
--- opengfs/configure.ac	2003-07-29 18:19:46.000000000 +0800
+++ opengfs-opendlm/configure.ac	2003-09-24 11:11:01.000000000 +0800
@@ -383,6 +383,20 @@
 	exec_prefix="";
 fi
 
+AC_ARG_ENABLE(
+	opendlm,
+	[  --enable-opendlm  Using opendlm],
+	[enable_opendlm=true])
+
+AM_CONDITIONAL(ENABLE_OPENDLM, test x$enable_opendlm = xtrue)
+
+dnl get the opendlm includes path.
+
+AC_ARG_WITH(opendlm_includes,
+	[  --with-opendlm_includes=DIR  dir for your opendlm package],
+	opendlm_includes="$withval")
+AC_SUBST(opendlm_includes)
+
 dnl default CFLAGS, can be overridden on command line
 dnl dv (29-Jul-2003):  This nukes debugging and is confusing.  Let the
person
 dnl who builds the package decide about optimisation.
@@ -437,6 +451,7 @@
 	src/locking/modules/memexp/Makefile
 	src/locking/modules/nolock/Makefile
 	src/locking/modules/stats/Makefile
+	src/locking/modules/opendlm/Makefile
 	src/locking/servers/Makefile
 	src/locking/servers/memexp/Makefile
 	src/pool/Makefile
diff -Naur opengfs/docs/HOWTO-opendlm opengfs-opendlm/docs/HOWTO-opendlm
--- opengfs/docs/HOWTO-opendlm	1970-01-01 08:00:00.000000000 +0800
+++ opengfs-opendlm/docs/HOWTO-opendlm	2003-09-24 11:11:18.000000000
+0800
@@ -0,0 +1,132 @@
+HOWTO use OpenDLM as the locking manager (V0.01)
+
+This document descries how to use OpenDLM as the locking mangaer in
+an OpenGFS cluster. It provides a simple example configuration for 
+a 2 nodes cluster. In order to understand this example, you also 
+need to read some documents from OpenGFS(HOWTO-nopool), OpenDLM 
+and HA heartbeat.
+
+BUILDING AND INSTALLING LOCKING MODULE FOR OPENDLM
+--------------------------------------------------
+
+1. Get HA heartbeat, OpenDLM and OpenGFS' source codes from:
+	http://www.linux-ha.org/heartbeat/
+	http://www.sf.net/projects/opendlm/
+	http://www.sf.net/projects/opengfs/
+
+2. Build and install HA heartbeat, OpenDLM.(For more information, 
+please read the documents from these two projects).
+
+3. Patch your kernel and reboot:
+	Please read section 1.b in HOWTO-nopool
+
+4. Build OpenGFS:
+	./bootstrap
+	./configure --enable-opendlm --with-opendlm_includes=/YOUR/PATH
+	make
+	make install
+	depmod -a
+
+5. Insert OpenGFS module:
+	modprobe ogfs
+ 
+6. Partition the shared drive:
+	Please read section 5 in HOWTO-nopool
+
+7. Make the OpenGFS Filesystem
+	Please read section 6 in HOWTO-nopool first.
+	
+	In order to use OpenDLM as the locking manager, we need 
+specify the locking protocol as "opendlm" when we make the filesystem.
+
+	mkfs.ogfs -p opendlm -t /dev/sdx1 -c journal.cf
+
+8. Configure the OpdnGFS Cluster.
+	Please read section 7 in HWWTO-nopool first.
+
+	# cat ogfscf.cf
+
+	datadev: /dev/sdx3
+	cidev: /dev/sdx1
+	lockdev: 192.168.0.37:15697
+	cbport: 3001
+
+	timeout: 30
+	STOMITH: manual
+	name: manual
+
+	node: 192.168.0.37 0 SM: manual 1
+	node: 192.168.0.203 1 SM: manual 2
+
+	NOTE: a. The "lockdev" and "cbport" in "ogfscf.cf" are useless now.
+	      b. The order of nodes is important, it should be the same in
+		 OpenDLM's config file.
+	
+9. Configure HA heartbeat and OpenDLM
+	For more detailed information, please read HA heartbeat and OpenDLM's
+	documents.	
+
+	#cat /etc/ha.d/ha.cf
+
+	debugfile /var/log/ha-debug
+	logfile /var/log/ha-log
+	logfacility     local0
+	bcast  eth0       # Linux
+	node    wv1		#192.168.0.37
+	node    wv2		#192.168.0.203
+
+	NOTE: ha.cf should be same in these two nodes.
+
+	#cat /etc/dlm.conf
+
+	NODECOUNT 2
+	1 wv1 192.168.0.37
+	2 wv2 192.168.0.203
+	DLMNAME haDLM
+	DLMMAJOR 250
+	DLMCMGR heartbeat
+	DLMADMIN admin 0
+	DLMLOCKS locks 1
+
+	NOTE:  a. dlm.conf should be same in these two nodes
+	       b. The order of nodes is important, it should be the same in
+               OpenGFS's config file.
+
+10. Start locking service
+
+	Start HA heartbeat:
+
+	On wv1:   #/etc/init.d/heartbeat start
+	On wv2:   #/etc/init.d/heartbeat start
+
+	Start OpenDLM:
+
+	On wv1:   #dlmdu -C /etc/dlm.conf
+	On wv2:   #dlmdu -C /etc/dlm.conf
+
+11. Mount the File system:
+	
+	a. Insert the locking module:
+		modprobe libdlmk
+		modprobe opendlm
+
+	b. Mkdir and mount file system:
+		mkdir /ogfs
+		mount -t ogfs /dev/sdx3 /ogfs -o hostdate=192.168.0.x
+
+SHUTTING DOWN CLEANLY
+---------------------
+
+1. Unmount file system:
+	umount /ogfs
+
+2. Stop OpenDLM and HA heartbeat:
+	killall dlmdu
+	/etc/init.d/heartbeat stop
+
+3. Unload the modules:
+	modprobe -r opendlm
+	modprobe -r ogfs
+	modprobe -r libdlmk
+	modprobe -r dlmdk.core
+
diff -Naur opengfs/docs/opendlm2glock opengfs-opendlm/docs/opendlm2glock
--- opengfs/docs/opendlm2glock	1970-01-01 08:00:00.000000000 +0800
+++ opengfs-opendlm/docs/opendlm2glock	2003-09-24 11:11:28.000000000
+0800
@@ -0,0 +1,137 @@
+Map OpenDLM to G-lock  (V0.01)
+
+This document describes the implementation details of the OpenDLM
locking module.
+You could find corresponding codes at src/locking/modules/opendlm/.
+
+1. How to implement all "lm_lockops".
+
+Fields in struct lm_lockops:
+
+* mount
+	Do almost same things as memexp locking module's mount function.
First, this 
+	function uses a hash value(hash the cidev's name) as ID of an ogfs
instance. 
+	Then this function reads cidev to get all cluster configuration
information.
+	At last, this function initializes deadman lock and return the
lockspace 
+	structure.
+
+	lockspace: 
+		Get lockspace basing on cidev(because different ogfs instants
+		using different cidev). Record lockspace and node's information(such
as
+		CB, fsdata, etc) in a private data sturct.
+
+		Following is the definition of lockspace structure:
+
+		struct opendlm {
+        		struct list_head        list;
+	        	char                    table_name[256];
+		        uint32                  name_space; /* hash value of
table_name */
+        		lm_callback_t           cb;
+	        	lm_fsdata_t             *fsdata;
+
+	        	struct file             *cfile;
+		        unsigned int            jid;
+        		unsigned int            nodes_count;
+		        struct opendlm_lock     *mount_lock;
+        		struct list_head        deadman;
+		};
+
+
+	
+	ls_jid: 
+		Get it by reading cidev.
+	
+	ls_first: 
+		Determined by using deadman lock. The first node grabs the mount lock
and
+		 blocks all other nodes untile "others_may_mount" is called. 
+
+
+*others_may_mount
+	Release the mount lock.
+
+*unmount
+	Clean up all data struct. 
+
+*get_lock 
+	Allocate and initialize a private lock struct.
+
+*put_lock
+	Clean and free a private lock struct.
+
+*lock
+	Do the lock operation.
+	Lock state translation:
+		LM_ST_UNLOCKED	->	NL
+		LM_ST_EXCLUSIVE	->	EX
+		LM_ST_SHARED	->	PR
+		LM_ST_DEFERRED	->	CW
+
+	Lock flag translation:
+		LM_FLAG_TRY	->	LKM_NOQUEUE
+		LM_FLAG_NOEXP	->	purge this lock first
+
+	Note: 	Shared locks are treated non-persistent.
+		Exclusive locks are treated persistent.
+		
+*unlock
+	Do the unlock operation
+
+*reset
+	Do the unlock operation. 
+
+*cancel
+	Cancel a lock/convert request.
+
+*hold_lvb
+	Specify LKM_VALBLK in all lock operations.	
+
+	Note: The default size of lvb in OpenDLM is 16 bytes, we need to
change
+		it to 32bytes.
+
+*unhold_lvb
+	N/A
+
+*sync_lvb
+	N/A
+
+*reset_exp
+	Purge all locks that hold by the failed node.
+
+
+Fields in struct lm_lockstruct
+
+*ls_jid
+See previous section.
+
+*ls_first
+See previous section.
+
+*ls_lockspace
+See previous section.
+
+*ls_ops
+See previous section.
+
+
+2. Private lock structure and lock name.
+Following is the definition of private lock structure:
+
+struct opendlm_lock {
+        struct opendlm_lockname lockname;
+        struct lockstatus       lksb;	/* Lock status block for
OpenDLM*/
+        lm_lvb_t                *lvb;	/* Lock value block */
+        struct opendlm          *dlm;
+        int                     done;	/* Used to implement the
synchronizing lock operations*/
+};
+
+Following is the definition of lock name:
+
+#define OGFS_DLM_MAGICLEN       4
+#define OGFS_DLM_MAGIC          "OGFS"
+
+struct opendlm_lockname {
+        uint64                  lock_num;	/*lock number*/
+        uint32                  name_space;	
+        unsigned int            lock_type;
+        char                    magic[OGFS_DLM_MAGICLEN];
+}__attribute__((packed));
+
diff -Naur opengfs/src/include/lm_interface.h
opengfs-opendlm/src/include/lm_interface.h
--- opengfs/src/include/lm_interface.h	2003-03-04 18:51:17.000000000
+0800
+++ opengfs-opendlm/src/include/lm_interface.h	2003-09-24
11:13:04.000000000 +0800
@@ -66,6 +66,7 @@
 #define LM_TYPE_PLOCK          (0x09)
 #define LM_TYPE_PLOCK_HEAD     (0x0A)
 #define LM_TYPE_LVB_MASK       (0x80)
+#define LM_TYPE_DEADMAN        (0x0B)
 
 /*  States passed to lock()  */
 
diff -Naur opengfs/src/locking/modules/Makefile.am
opengfs-opendlm/src/locking/modules/Makefile.am
--- opengfs/src/locking/modules/Makefile.am	2002-09-18
18:20:15.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/Makefile.am	2003-09-24
11:12:00.000000000 +0800
@@ -1,2 +1,7 @@
 # -*-Makefile-*-
-SUBDIRS = nolock memexp stats
+if ENABLE_OPENDLM
+opendlmdir = opendlm
+endif
+
+SUBDIRS = nolock memexp stats $(opendlmdir)
+
diff -Naur opengfs/src/locking/modules/opendlm/cluster_config.h
opengfs-opendlm/src/locking/modules/opendlm/cluster_config.h
--- opengfs/src/locking/modules/opendlm/cluster_config.h	1970-01-01
08:00:00.000000000 +0800
+++
opengfs-opendlm/src/locking/modules/opendlm/cluster_config.h	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,57 @@
+/*
+ *
+ *    Copyright 1999-2001 Sistina Software, Inc.
+ *
+ *    This is free software released under the GNU General Public
License.
+ *    There is no warranty for this software.  See the file COPYING for
+ *    details.
+ *
+ *    See the file AUTHORS for a list of contributors.
+ *
+ *    This file was maintained by:
+ *      David C. Teigland <teigland@sistina.com>
+ *
+ */
+#ifndef _CLUSTER_CONFIG_H
+#define _CLUSTER_CONFIG_H
+
+//#include "ogfs_ondisk.h"
+#include "global.h"
+
+#define OGFS_LOCKNAME_LEN	(64)
+
+#define OGFS_CLUSTER_GLOBAL  (0x47465341)
+#define OGFS_CLUSTER_NODE    (0x47465342)
+
+#define OGFS_CLUSTER_VERSION (0x47010000)
+
+#define CIDEV_BLOCKSIZE     (4096)
+
+/*  First sector of cidev  */
+
+struct cluster_global {
+	uint32	cg_magic;	/* magic number */
+	uint32	cg_version;	/* version number */
+	char	cg_lockdev[64];	/* lock device */
+	char	cg_datadev[64];	/* data device */
+	uint32	cg_cbport;	/* call-back port */
+	uint32	cg_node_timeout;	/* in seconds */
+};
+typedef struct cluster_global cluster_global_t;
+
+/*  One struct per sector.  Implicit: JID = block - 1  */
+
+struct cluster_node {
+	uint32	cn_magic;	/* Magic number */
+	uint32	cn_ipaddr;	/* IP address of node */
+	uint32	cn_cid;		/* Client ID of node */
+	uint32	cn_num_stomith;	/* Number of stomith structs */
+};
+typedef struct cluster_node cluster_node_t;
+
+/*  On-disk format translation functions  */
+
+void cluster_global_in(struct cluster_global *cg, char *buf);
+void cluster_node_in(struct cluster_node *cn, char *buf);
+
+#endif /* _CLUSTER_CONFIG_H */
diff -Naur opengfs/src/locking/modules/opendlm/cluster_ondisk.c
opengfs-opendlm/src/locking/modules/opendlm/cluster_ondisk.c
--- opengfs/src/locking/modules/opendlm/cluster_ondisk.c	1970-01-01
08:00:00.000000000 +0800
+++
opengfs-opendlm/src/locking/modules/opendlm/cluster_ondisk.c	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,66 @@
+/*
+ *
+ *    Copyright 1995-2001 Regents of the University of Minnesota
+ *
+ *    This is free software released under the GNU General Public
License.
+ *    There is no warranty for this software.  See the file COPYING for
+ *    details.
+ *
+ *    See the file AUTHORS for a list of contributors.
+ *
+ *    This file was maintained by:
+ *      David C. Teigland  <teigland@sistina.com>
+ *
+ */
+
+#include "config.h"
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/string.h>
+#include "osi.h"
+#else /* __KERNEL__ */
+#include <string.h>
+#include "osi_endian.h"
+#endif /* __KERNEL__ */
+
+#include "cluster_config.h"
+
+#define CPIN_8(x, y, z) {memcpy((x), (y), (z));}
+#define CPOUT_8(x, y, z) {memcpy((y), (x), (z));}
+#define CPIN_16(x, y) {(x) = be16_to_cpu((y));}
+#define CPOUT_16(x, y) {(y) = cpu_to_be16((x));}
+#define CPIN_32(x, y) {(x) = be32_to_cpu((y));}
+#define CPOUT_32(x, y) {(y) = cpu_to_be32((x));}
+#define CPIN_64(x, y) {(x) = be64_to_cpu((y));}
+#define CPOUT_64(x, y) {(y) = cpu_to_be64((x));}
+
+
+/*  Nothing STOMITH-specific below  */
+
+void
+cluster_global_in(cluster_global_t * cg, char *buf)
+{
+	cluster_global_t *bufcg = (cluster_global_t *) buf;
+
+	CPIN_32(cg->cg_magic, bufcg->cg_magic);
+	CPIN_32(cg->cg_version, bufcg->cg_version);
+
+	CPIN_8(cg->cg_lockdev, bufcg->cg_lockdev, OGFS_LOCKNAME_LEN);
+	CPIN_8(cg->cg_datadev, bufcg->cg_datadev, OGFS_LOCKNAME_LEN);
+
+	CPIN_32(cg->cg_cbport, bufcg->cg_cbport);
+	CPIN_32(cg->cg_node_timeout, bufcg->cg_node_timeout);
+}
+
+void
+cluster_node_in(cluster_node_t * cn, char *buf)
+{
+	cluster_node_t *bufcn = (cluster_node_t *) buf;
+
+	CPIN_32(cn->cn_magic, bufcn->cn_magic);
+	CPIN_32(cn->cn_ipaddr, bufcn->cn_ipaddr);
+	CPIN_32(cn->cn_cid, bufcn->cn_cid);
+	CPIN_32(cn->cn_num_stomith, bufcn->cn_num_stomith);
+}
+
diff -Naur opengfs/src/locking/modules/opendlm/deadman.c
opengfs-opendlm/src/locking/modules/opendlm/deadman.c
--- opengfs/src/locking/modules/opendlm/deadman.c	1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/deadman.c	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,236 @@
+/* -*- linux-c -*- */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**  
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**  
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
+**  
+*/
+
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+
+
+#include <lm_interface.h>
+#include "opendlm.h"
+
+#define OGFS_DLM_SUCCESS	0
+#define OGFS_DLM_FAILED		1
+#define OGFS_DLM_NONFIRST	2
+
+struct deadman_lock {
+	struct list_head	list;
+	struct opendlm_lock	lock;
+};
+
+struct timer_list refresh_timer;
+void deadman_block_others(void *bastargs, int mode);
+
+void ignore_bast(void *bastargs, int mode)
+{
+	return;
+}
+
+void ignore_ast(void *bastargs)
+{
+	return;
+}
+
+void ignore_unlockast(void *unlockastargs, int lstat, void* extrap)
+{
+	return;
+}
+
+void other_node_die(void* bastargs)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)bastargs;
+	struct opendlm *dlm = lock->dlm;
+
+	if(!dlm) {
+		err("Can not find failed node!");
+		return;
+	}
+	
+	dlm->cb(dlm->fsdata, LM_CB_EXPIRED, 
+		(void *)(&lock->lockname.lock_num));
+}
+
+void refresh_deadman_lock(unsigned long arg)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)arg;
+
+	del_timer(&refresh_timer);
+
+	dlmunlock(lock->lksb.lockid, NULL, LKM_FORCE, ignore_unlockast, NULL,
NULL);
+
+	dlmlock(LKM_CRMODE, &lock->lksb, 0, (void *)(&lock->lockname),
+			 sizeof(struct opendlm_lockname), other_node_die,
+			 (void *)lock, deadman_block_others);
+	return;
+}
+
+
+void deadman_block_others(void *bastargs, int mode)
+{
+	init_timer(&refresh_timer);
+
+	refresh_timer.expires = 1*HZ;
+	refresh_timer.data = (unsigned long)bastargs;
+	refresh_timer.function = refresh_deadman_lock;
+
+	add_timer(&refresh_timer);	
+
+	return;
+}
+
+void cleanup_deadman_list(struct opendlm *dlm)
+{
+	struct deadman_lock *tmp;
+
+	tmp = list_entry(dlm->deadman.next, typeof(*tmp), list);
+
+	while(&tmp->list != &dlm->deadman){
+		dbg("clean up deadman list");
+		
+		dlmunlock(tmp->lock.lksb.lockid, NULL, LKM_FORCE, 
+				ignore_unlockast, NULL, NULL);
+		list_del(&tmp->list);
+		kfree(tmp);
+		tmp = list_entry(dlm->deadman.next, 
+			typeof(*tmp), list);
+	}
+}
+
+
+int init_deadman(struct opendlm *dlm, int first)
+{
+	unsigned int lock_num;
+	struct deadman_lock *deadman;
+	dlm_stats_t status;
+
+	dbg("enter init_deadman, nodes_count  %d!", dlm->nodes_count);
+
+	for(lock_num = 0; lock_num < dlm->nodes_count; lock_num++){
+		deadman = (struct deadman_lock *)kmalloc(sizeof(struct deadman_lock),
GFP_KERNEL);
+		if(!deadman)
+			return OGFS_DLM_FAILED;
+
+		memset(deadman, 0, sizeof(struct deadman_lock));
+
+		strncpy(deadman->lock.lockname.magic, OGFS_DLM_MAGIC,
OGFS_DLM_MAGICLEN);
+		deadman->lock.lockname.name_space = dlm->name_space;
+		deadman->lock.lockname.lock_num = (unsigned long long)lock_num;
+		deadman->lock.lockname.lock_type = LM_TYPE_DEADMAN;
+		deadman->lock.dlm = dlm;
+
+		dbg("before get deadman lock!lksb: %p", &deadman->lock.lksb);
+
+		if(lock_num != dlm->jid){
+			if(first){
+				dbg("first&others");
+				status = my_dlmlock_sync(LKM_EXMODE, &deadman->lock.lksb,
LKM_NOQUEUE, &deadman->lock,
+							deadman_block_others);
+			} else {
+				dbg("non-first&others");
+				status = dlmlock(LKM_CRMODE, &deadman->lock.lksb, 0, (void
*)(&deadman->lock.lockname),
+							sizeof(struct opendlm_lockname), other_node_die,
+							(void *)&deadman->lock, deadman_block_others);
+			}
+		} else {
+			dbg("myself");
+			status = my_dlmlock_sync(LKM_EXMODE, &(deadman->lock.lksb), 0,
&(deadman->lock), ignore_bast);
+		}
+
+		dbg("after get deadman lock!lksb: %p, status %d",
&deadman->lock.lksb, status);
+
+		if(status != DLM_NORMAL){
+			kfree(deadman);
+			return OGFS_DLM_FAILED; 
+		}
+
+		dbg("deadman success");
+		
+		if(first && deadman->lock.lksb.status != DLM_NORMAL){
+			kfree(deadman);
+			return OGFS_DLM_NONFIRST;
+		}
+
+		list_add(&deadman->list, &dlm->deadman);
+	}
+
+	dbg("exit init deadman!");
+
+	return OGFS_DLM_SUCCESS;
+}
+
+int start_deadman_lock(struct opendlm *dlm, unsigned int *first)
+{
+	int error;
+	
+	dbg("enter start deadman!");
+
+	error = grab_mount_lock(dlm);
+	if(error)
+		return -1;
+
+	dbg("grab_mount_lock %d!", error);
+
+	error = init_deadman(dlm, 1);
+
+	dbg("init deadman %d!", error);
+
+	switch (error) {
+
+	case OGFS_DLM_FAILED:
+		cleanup_deadman_list(dlm);
+		release_mount_lock(dlm);
+		return -1;
+
+	case OGFS_DLM_NONFIRST:
+		cleanup_deadman_list(dlm);
+		release_mount_lock(dlm);
+		break;
+	case OGFS_DLM_SUCCESS:
+		*first = TRUE;
+		return 0;
+	}
+
+	*first = FALSE;
+	error = init_deadman(dlm, 0);
+
+	dbg("2nd init deadman %d!", error);
+
+	if(error == OGFS_DLM_FAILED){
+		cleanup_deadman_list(dlm);
+		release_mount_lock(dlm);
+		return -1;
+	}
+
+	dbg("exit start deadman!");
+
+	return 0;
+}
+
+int stop_deadman_lock(struct opendlm *dlm)
+{
+	cleanup_deadman_list(dlm);
+	return 0;
+}
diff -Naur opengfs/src/locking/modules/opendlm/dlm.c
opengfs-opendlm/src/locking/modules/opendlm/dlm.c
--- opengfs/src/locking/modules/opendlm/dlm.c	1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/dlm.c	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,343 @@
+/* -*- linux-c -*- */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**  
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**  
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
+**  
+*/
+
+/* Some codes are copied from Sistina Software Inc's GFS */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/kmod.h>
+#include <linux/list.h>
+
+#include <lm_interface.h>
+#include "opendlm.h"
+
+int debug=0;
+MODULE_PARM(debug, "i");
+
+LIST_HEAD(dlm_list);
+struct lm_lockops opendlm_ops;
+
+lm_lockspace_t *opendlm_mount(char *table_name, char *host_data,
lm_callback_t cb, 
+			      lm_fsdata_t * fsdata,unsigned int *jid, unsigned int *first)
+{
+	struct opendlm *dlm;
+	char name[256];
+	uint32 ip;
+	uint32 hash;
+	int error;
+
+	dbg("enter mount!");
+	
+	MOD_INC_USE_COUNT;
+
+	name[255] = '\0';
+	strncpy(name, table_name, 255);
+	hash = locktable_hash(table_name, strlen(table_name));
+
+	inet_aton(host_data, &ip);
+
+	/*  Check to make sure this lock table isn't already being used  */
+
+	dbg("find_dlm! table_name %s hash %d", table_name, hash);
+	dlm = find_dlm(hash);
+	if(dlm) {
+		err("\"%s\" encount a name space collision", name);
+		goto fail;
+	}
+
+	/*  Set up our main structure  */
+
+	dlm = (struct opendlm *)kmalloc(sizeof(struct opendlm), GFP_KERNEL);
+	if (!dlm) {
+		err("out of memory");
+		goto fail;
+	}
+	memset(dlm, 0, sizeof(struct opendlm));
+
+	strcpy(dlm->table_name, name);
+
+	dlm->cb = cb;
+	dlm->fsdata = fsdata;
+	dlm->name_space = hash;
+	INIT_LIST_HEAD(&dlm->deadman);
+	
+	dbg("file open!");
+
+	dlm->cfile = filp_open(name, O_RDONLY, 0);
+	if (IS_ERR(dlm->cfile)) {
+		err("open error %ld", PTR_ERR(dlm->cfile));
+		dlm->cfile = NULL;
+	}
+	if (!dlm->cfile) {
+		err("can't open cidev %s", name);
+		goto fail_free_dlm;
+	}
+
+	if (!S_ISBLK(dlm->cfile->f_dentry->d_inode->i_mode)) {
+		err("cidev %s is not a blockdevice", name);
+		goto fail_free_dlm;
+	}
+
+	/*  Get information from cidev  */
+
+	dbg("setup jid!");
+
+	error = setup_jid(dlm, ip);
+	if (error) {
+		err("bad parameters from %s", name);
+		goto fail_dput;
+	}
+	*jid = dlm->jid;
+
+	/*  Wait for possible mount state recovery  */
+
+	dbg("start deadman lock!");
+
+	error = start_deadman_lock(dlm, first);
+	if (error < 0) {
+		err("start deadman lock failed (%d)", error);
+		goto fail_dput;
+	}
+
+	list_add(&dlm->list, &dlm_list);
+
+	dbg("normal exit!");
+
+	return ((lm_lockspace_t *) dlm);
+
+fail_dput:
+	filp_close(dlm->cfile, NULL);
+
+fail_free_dlm:
+	kfree(dlm);
+
+fail:
+	MOD_DEC_USE_COUNT;
+
+	err("failed exit!");
+
+	return (NULL);
+}
+
+void opendlm_others_may_mount(lm_lockspace_t * lockspace)
+{
+	/*unlock mount lock*/
+	release_mount_lock((struct opendlm *)lockspace);
+}
+
+void opendlm_unmount(lm_lockspace_t * lockspace)
+{
+	struct opendlm *dlm = (struct opendlm *)lockspace;
+	struct opendlm *tmp;
+	int done = FALSE;
+
+	list_for_each_entry(tmp, &dlm_list, list)
+		if (tmp == dlm) {
+			list_del(&dlm->list);
+			done = TRUE;
+			break;
+		}
+
+	if(!done) {
+		err("given a weird lockspace pointer");
+	} else {
+		stop_deadman_lock(dlm);
+		filp_close(dlm->cfile, NULL);
+		kfree(dlm);
+	}
+	MOD_DEC_USE_COUNT;
+}
+
+lm_lock_t *opendlm_get_lock(lm_lockspace_t * lockspace, lm_lockname_t *
name)
+{
+	struct opendlm_lock *lock;
+	struct opendlm *dlm = (struct opendlm *)lockspace;
+
+	lock = (struct opendlm_lock *)kmalloc(sizeof(struct opendlm_lock),
GFP_KERNEL);
+	if(!lock)
+		goto lock_failed;
+
+	memset(lock, 0, sizeof(struct opendlm_lock));
+
+	lock->lvb = (lm_lvb_t *)kmalloc(sizeof(lm_lvb_t), GFP_KERNEL);
+
+	if(lock->lvb == NULL)
+		goto lvb_failed;
+
+	lock->lvb->lvb_data = (char *)&lock->lksb.value;
+	lock->lvb->lvb_length = MAXLOCKVAL;
+	
+	strncpy(lock->lockname.magic, OGFS_DLM_MAGIC, OGFS_DLM_MAGICLEN);
+	lock->lockname.name_space = dlm->name_space;
+	lock->lockname.lock_type = name->ln_type;
+	lock->lockname.lock_num = name->ln_number;
+	lock->dlm = dlm;
+	lock->done = 0;
+	
+	return (lm_lock_t *)lock;
+
+ lvb_failed:
+	kfree(lock);
+ lock_failed:
+	return NULL;
+}
+
+void opendlm_put_lock(lm_lock_t * lk)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+	kfree(lock->lvb);
+	kfree(lock);
+}
+
+int opendlm_lock(lm_lock_t * lk, unsigned int cur_state, unsigned int
req_state, 
+		 unsigned int flags)
+{
+	dlm_stats_t status;
+	struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+	int node_id = lock->dlm->jid + 1; /* node_id = jid+1; specified in
config file*/
+	int lockmode = 0;
+	int lockflags = 0;
+
+	dbg("lock number %Ld", lock->lockname.lock_num);
+
+	parse_lockreq(cur_state, req_state, &lockmode, &lockflags);
+	
+	if (flags | LM_FLAG_TRY){
+		lockflags |= LKM_NOQUEUE;
+	}
+	
+	if (flags | LM_FLAG_NOEXP) {
+		dlm_purge(node_id, 0, 0);
+	}
+
+	lockflags |= LKM_VALBLK;
+
+	status = my_dlmlock_sync(lockmode, &lock->lksb, lockflags, (void
*)lock, block_others);
+
+	if(status != DLM_NORMAL) {
+		err("opendlm_lock invalid param");
+		goto fail; 
+	}
+	
+	if(lock->lksb.status != DLM_NORMAL) {
+		dbg("opendlm_lock can't grab lock, status %d", lock->lksb.status);
+		goto fail;
+	}
+	
+	return req_state;
+
+ fail:
+	if (status == DLM_CANCEL)
+		return OPENDLM_CANCELED;
+	
+	if (lock->lksb.status == DLM_NOTQUEUED)
+		return OPENDLM_TRYFAILED;
+	
+	return -1;
+}
+
+int opendlm_unlock(lm_lock_t * lk, unsigned int cur_state)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+	dlmunlock(lock->lksb.lockid, lock->lvb->lvb_data,
LKM_FORCE|LKM_VALBLK,
+			ignore_unlockast, NULL, NULL);
+
+	return 0;
+}
+
+int opendlm_reset(lm_lock_t * lk)
+{
+        struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+        dlmunlock(lock->lksb.lockid, NULL, LKM_FORCE, 
+			ignore_unlockast, NULL, NULL);
+
+        return 0;
+}
+
+void opendlm_cancel(lm_lock_t * lk, int on)
+{
+        struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+	
+	dlmunlock(lock->lksb.lockid, NULL, LKM_CANCEL,
+			ignore_unlockast, NULL, NULL);
+}
+
+lm_lvb_t *opendlm_hold_lvb(lm_lock_t * lk)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+	return lock->lvb;
+}
+
+void opendlm_unhold_lvb(lm_lock_t * lk, lm_lvb_t * lvb)
+{
+	return;
+}
+
+void opendlm_sync_lvb(lm_lock_t * lk, lm_lvb_t * lvb)
+{
+	return;
+}
+
+void opendlm_reset_exp(lm_lockspace_t * lockspace, unsigned int jid)
+{
+	dlm_purge(jid+1, 0, 0);
+}
+
+struct lm_lockops opendlm_ops = {
+	proto_name:		PROTO_NAME,
+	mount:			opendlm_mount,
+	others_may_mount:	opendlm_others_may_mount,
+	unmount:		opendlm_unmount,
+	get_lock:		opendlm_get_lock,
+	put_lock:		opendlm_put_lock,
+	lock:			opendlm_lock,
+	unlock:			opendlm_unlock,
+	reset:			opendlm_reset,
+	cancel:			opendlm_cancel,
+	hold_lvb:		opendlm_hold_lvb,
+	unhold_lvb:		opendlm_unhold_lvb,
+	sync_lvb:		opendlm_sync_lvb,
+	reset_exp:		opendlm_reset_exp,
+};
+
+
+int opendlm_start(void)
+{
+	return lm_register_proto(&opendlm_ops);
+}
+
+void opendlm_stop(void)
+{
+	return lm_unregister_proto(&opendlm_ops);
+}
+
+module_init(opendlm_start);
+module_exit(opendlm_stop);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stanley Wang");
+MODULE_DESCRIPTION("Locking module for using OpenDLM");
diff -Naur opengfs/src/locking/modules/opendlm/Makefile.am
opengfs-opendlm/src/locking/modules/opendlm/Makefile.am
--- opengfs/src/locking/modules/opendlm/Makefile.am	1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/Makefile.am	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,27 @@
+# -*-Makefile-*-
+
+#
+#    Copyright 2001 The OpenGFS Project
+#
+#    This is free software released under the GNU General Public
License.
+#    There is no warranty for this software.  See the file COPYING for
+#    details.
+#
+#    See the file AUTHORS for a list of contributors.
+#
+
+EXTRA_INCL = \
+	-I$(top_srcdir)/src/fs -I$(top_srcdir)/src/pool \
+	-I$(top_srcdir)/src/stomith/module \
+	-I$(opendlm_includes)
+
+include $(top_srcdir)/make/modules.mk
+
+module_PROGRAMS = opendlm.o
+opendlm_o_SOURCES = dlm.c deadman.c misc.c cluster_ondisk.c
cluster_config.h opendlm.h
+
+EXEEXT =
+opendlm.o$(EXEEXT): $(opendlm_o_OBJECTS)
+	$(KLD) -r $^ -o $@
+
+
diff -Naur opengfs/src/locking/modules/opendlm/misc.c
opengfs-opendlm/src/locking/modules/opendlm/misc.c
--- opengfs/src/locking/modules/opendlm/misc.c	1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/misc.c	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,428 @@
+/* -*- linux-c -* */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**  
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**  
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**  
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
+**  
+*/
+
+
+/* Some codes are copied from Sistina Software Inc's GFS */
+
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/kdev_t.h>
+#include <linux/timer.h>
+
+#include <lm_interface.h>
+#include <cluster_config.h>
+#include <crc.h>
+#include "opendlm.h"
+
+struct cb_args 
+{
+	void			*bastargs;
+	int			mode;
+};
+
+
+struct opendlm *find_dlm(uint32 namespace)
+{
+	struct opendlm *tmp;
+	
+	list_for_each_entry(tmp, &dlm_list, list) {
+		if (tmp->name_space == namespace) {
+			return tmp;
+		}
+	}
+	return NULL;
+}
+
+
+int setup_jid(struct opendlm *dlm, uint32 ip)
+{
+	struct buffer_head *bh;
+	cluster_global_t cg;
+	cluster_node_t cn;
+	int block = 0, found = 0;
+	kdev_t dev;
+
+	dev = dlm->cfile->f_dentry->d_inode->i_rdev;
+	set_blocksize(dev, CIDEV_BLOCKSIZE);
+
+	bh = bread(dev, 0, CIDEV_BLOCKSIZE);
+	if (!bh) {
+		err("can't read Cluster Information Device");
+		return (-1);
+	}
+
+	cluster_global_in(&cg, bh->b_data);
+
+	if (cg.cg_magic != OGFS_CLUSTER_GLOBAL) {
+		mark_buffer_uptodate(bh, FALSE);
+		brelse(bh);
+		return (-1);
+	}
+
+	if ((((cg.cg_version >> 16) & 0xff) !=
+	     ((OGFS_CLUSTER_VERSION >> 16) & 0xff))
+	    || (((cg.cg_version >> 8) & 0xff) !=
+		((OGFS_CLUSTER_VERSION >> 8) & 0xff))) {
+		mark_buffer_uptodate(bh, FALSE);
+		brelse(bh);
+		err("version mismatch: cidev (%u, %u), memexp (%u, %u)",
+		     (cg.cg_version >> 16) & 0xff,
+		     (cg.cg_version >> 8) & 0xff,
+		     (OGFS_CLUSTER_VERSION >> 16) & 0xff,
+		     (OGFS_CLUSTER_VERSION >> 8) & 0xff);
+		return (-1);
+	}
+
+	mark_buffer_uptodate(bh, FALSE);
+	brelse(bh);
+
+	block++;
+
+	/*  Read cluster info  */
+
+	while (1) {
+		bh = bread(dev, block, CIDEV_BLOCKSIZE);
+
+		if (!bh) {
+			err("error reading Cluster Information Device.");
+			goto fail;
+		}
+
+		cluster_node_in(&cn, bh->b_data);
+
+		if (cn.cn_magic == OGFS_CLUSTER_GLOBAL) {	/* end of the configured
nodes */
+			mark_buffer_uptodate(bh, FALSE);
+			brelse(bh);
+			break;
+		}
+
+		if (cn.cn_magic != OGFS_CLUSTER_NODE)	/* a node was removed from the
config */
+			goto next;
+
+		if (cn.cn_ipaddr == ip) {	/* our own config block */
+			dlm->jid = block - 1;
+			found = TRUE;
+		}
+
+	      next:
+		mark_buffer_uptodate(bh, FALSE);
+		brelse(bh);
+		block++;
+	}
+
+	if (!found) {
+		char ipstr[16];
+		inet_ntoa(ip, ipstr);
+		err("no cluster info for %s", ipstr);
+		goto fail_2;
+	}
+
+	dlm->nodes_count = block - 1;
+ 
+	return (0);
+
+      fail:
+
+	if (bh) {
+		mark_buffer_uptodate(bh, FALSE);
+		brelse(bh);
+	}
+
+      fail_2:
+
+	return (-1);
+}
+
+int grab_mount_lock(struct opendlm *dlm)
+{
+	struct opendlm_lock *lock;
+	dlm_stats_t status;
+
+	lock = (struct opendlm_lock *)kmalloc(sizeof(struct opendlm_lock),
GFP_KERNEL);
+
+	if(!lock)
+		return -1;
+
+	memset(lock, 0, sizeof(struct opendlm_lock));
+
+	strncpy(lock->lockname.magic, OGFS_DLM_MAGIC, OGFS_DLM_MAGICLEN);
+	lock->lockname.name_space = dlm->name_space;
+	lock->lockname.lock_type = LM_TYPE_MOUNT;
+	lock->lockname.lock_num = 0;
+	lock->dlm = dlm;
+
+	status = my_dlmlock_sync(LKM_EXMODE, &lock->lksb, 0, lock,
ignore_bast);
+
+	if(status != DLM_NORMAL)
+		return -1; 
+
+	if(lock->lksb.status != DLM_NORMAL)
+		return -1;
+
+	dlm->mount_lock = lock;
+
+	return 0;
+}
+
+void release_mount_lock(struct opendlm *dlm)
+{
+	dlmunlock(dlm->mount_lock->lksb.lockid, NULL, LKM_FORCE,
ignore_unlockast, NULL, NULL);
+	kfree(dlm->mount_lock);
+}
+
+void parse_lockreq(unsigned int cur_state, unsigned int req_state, int
*lockmode, int *lockflags)
+{
+	if(cur_state != LM_ST_UNLOCKED) {
+		*lockflags |= LKM_CONVERT;
+	}
+	
+	switch(req_state){
+	case LM_ST_EXCLUSIVE:
+		*lockmode = LKM_EXMODE;
+		*lockflags |= LKM_ORPHAN;
+		break;
+	case LM_ST_SHARED:
+		*lockmode = LKM_PRMODE;
+		break;
+	case LM_ST_DEFERRED:
+                *lockmode = LKM_CWMODE;
+                break;
+	default:
+		err("Invalid lock state %d", req_state);
+	}
+}
+
+
+void lock_ast(void *astarg)
+{
+	struct opendlm_lock *lock = (struct opendlm_lock *)astarg;
+	dbg("enter lock_ask");
+
+	lock->done = 1;
+
+	dbg("exit lock_ast");
+}
+
+
+dlm_stats_t my_dlmlock_sync(int mode, struct lockstatus *lksb, int
flags,
+			    struct opendlm_lock *lock, dlm_bastlockfunc_t * bast)
+{
+	dlm_stats_t status;
+	dbg("enter my_dlmlock_sync");
+
+	dbg("mode %d lksb %p flags %d lockname %s lock %p", mode, lksb, flags,
(char *)(&lock->lockname), lock);
+	status = dlmlock(mode, lksb, flags, (void *)(&lock->lockname),
+				 sizeof(struct opendlm_lockname), lock_ast,
+				(void *)lock, bast);
+
+	dbg("after dlmlock");
+
+	if(status != DLM_NORMAL)
+		goto out; 
+
+ sleep:
+	if(!lock->done) {
+		current->policy |= SCHED_YIELD;
+		schedule();
+		goto sleep;
+	}
+	
+	lock->done = 0;
+	
+ out:
+	return status;
+}
+
+
+
+
+void opendlm_cb(void *args)
+{
+	struct cb_args *p = (struct cb_args *)args;
+	struct opendlm_lock *lock = (struct opendlm_lock *)(p->bastargs);
+	struct tq_struct *tqp = container_of(args, struct tq_struct, data);
+	lm_lockname_t name;
+	
+
+	name.ln_type = lock->lockname.lock_type;
+	name.ln_number = lock->lockname.lock_num;
+
+	schedule_timeout(1*HZ);
+	
+	switch(p->mode) {
+	case LKM_EXMODE:
+		lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_E, (void *)&name);
+		break;
+
+	case LKM_PRMODE:
+		lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_S, (void *)&name);
+		break;
+
+	case LKM_CWMODE:
+		lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_D, (void *)&name);
+		break;
+		
+	default:
+		err("Unknown lock mode %d!", p->mode);
+	}
+
+	kfree(p);
+	kfree(tqp);
+	
+	return;
+}
+ 
+
+void block_others(void *bastargs, int mode)
+{
+	struct tq_struct *tqp = NULL;
+	struct cb_args *p;
+
+	tqp = (struct tq_struct *)kmalloc(sizeof(struct tq_struct),
GFP_KERNEL);
+	
+	if (!tqp) {
+		err("Can't alloc memeory for tq!");
+		return;
+	}
+
+	/*FIXME: How to deal with kmalloc fail? maintain a pool?*/
+	p = (struct cb_args *)kmalloc(sizeof(struct cb_args), GFP_KERNEL);
+
+	if (!p) {
+		err("Can't alloc memory for cb_args!");
+		kfree(tqp);
+		return;
+	}
+
+	p->bastargs = bastargs;
+	p->mode = mode;
+	
+        tqp->sync = 0;	
+        INIT_LIST_HEAD(&(tqp->list));
+        tqp->routine = opendlm_cb;
+        tqp->data = (void *)p;
+
+	/*Fixme schedule_task may fail*/
+	schedule_task(tqp);
+	
+	return;
+}
+
+
+/*                                                                                                                                            
+
*                                                                                                                                            
+ *    Copyright 1995-1999 Regents of the University of
Minnesota                                                                              
+ *    Portions Copyright 2001 Sistina Software,
Inc.                                                                                          
+
*                                                                                                                                            
+ *    This is free software released under the GNU General Public
License.                                                                    
+ *    There is no warranty for this software.  See the file COPYING
for                                                                       
+ *   
details.                                                                                                                                
+
*                                                                                                                                            
+ *    See the file AUTHORS for a list of
contributors.                                                                                        
+
*                                                                                                                                           
+ */
+
+
+/**
+ * locktable_hash - hash an array of data
+ * @data: the data to be hashed
+ * @len: the length of data to be hashed
+ *
+ * Take some data and convert it to a 32-bit hash.
+ *
+ * The hash function is a 32-bit CRC of the data.  The algorithm uses
+ * the crc_32_tab table above.
+ *
+ * This may not be the fastest hash function, but it does a fair bit
better
+ * at providing uniform results than the others I've looked at.  That's
+ * really important for efficient directories.
+ *
+ * Returns: the hash
+ */
+
+uint32
+locktable_hash(const char *data, int len)
+{
+	uint32 hash = 0xFFFFFFFF;
+
+	for (; len--; data++)
+		hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8);
+
+	hash = ~hash;
+
+	return (hash);
+}
+
+int atoi(char *c)
+{
+	int x = 0;
+
+	while ('0' <= *c && *c <= '9') {
+		x = x * 10 + (*c - '0');
+		c++;
+	}
+
+	return (x);
+}
+
+int inet_aton(char *ascii, uint32 * ip)
+{
+	uint32 value;
+	int x;
+
+	*ip = 0;
+
+	for (x = 0; x < 4; x++) {
+		value = atoi(ascii);
+		if (value > 255)
+			return (-1);
+		*ip = (*ip << 8) | value;
+		if (x != 3) {
+			ascii = strstr(ascii, ".");
+		if (!ascii)
+			return (-1);
+		ascii++;
+		}
+	}
+	return (0);
+}
+
+void inet_ntoa(uint32 ip, char *buf)
+{
+	int i;
+	char *p;
+
+	p = buf;
+	for (i = 3; i >= 0; i--) {
+		p += sprintf(p, "%d", (ip >> (8 * i)) & 0xFF);
+	if (i > 0)
+		*(p++) = '.';
+	}
+	
+}
diff -Naur opengfs/src/locking/modules/opendlm/opendlm.h
opengfs-opendlm/src/locking/modules/opendlm/opendlm.h
--- opengfs/src/locking/modules/opendlm/opendlm.h	1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/opendlm.h	2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,106 @@
+/* -*- linux-c -*- */
+
+#include <dlm.h>
+
+#define PROTO_NAME "opendlm"
+#define OPENDLM_TRYFAILED (13)
+#define OPENDLM_CANCELED  (14)
+
+
+struct opendlm_lock;
+
+struct opendlm {
+	struct list_head	list;
+	char			table_name[256];
+	uint32			name_space; /* hash value of table_name */
+	lm_callback_t		cb;
+	lm_fsdata_t		*fsdata;
+
+	struct file		*cfile;
+	unsigned int		jid;
+	unsigned int		nodes_count;
+	struct opendlm_lock	*mount_lock;
+	struct list_head	deadman;
+};
+
+#define OGFS_DLM_MAGICLEN	4
+#define OGFS_DLM_MAGIC		"OGFS"
+
+struct opendlm_lockname {
+	uint64			lock_num;
+	uint32			name_space;
+	unsigned int		lock_type;
+	char			magic[OGFS_DLM_MAGICLEN];
+}__attribute__((packed));
+
+struct opendlm_lock {
+	struct opendlm_lockname	lockname;
+	struct lockstatus	lksb;
+	lm_lvb_t		*lvb;
+	struct opendlm		*dlm;
+	int			done;
+};
+
+extern struct list_head dlm_list;
+
+/* function defined in deadman.c */
+void ignore_bast(void *bastargs, int mode);
+void ignore_ast(void *bastargs);
+void ignore_unlockast(void *unlockast, int lstat, void *extrap);
+int start_deadman_lock(struct opendlm *dlm, unsigned int *first);
+int stop_deadman_lock(struct opendlm *dlm);
+
+/* function defined in misc.c */
+struct opendlm* find_dlm(uint32 namespace);
+int setup_jid(struct opendlm *dlm, uint32 ip);
+int grab_mount_lock(struct opendlm *dlm);
+void release_mount_lock(struct opendlm *dlm);
+void parse_lockreq(unsigned int cur_state, unsigned int req_state, int
*lockmode, int *lockflags);
+uint32 locktable_hash(const char *data, int len);
+void block_others(void *bastargs, int mode);
+int inet_aton(char *ascii, uint32 * ip);
+void inet_ntoa(uint32 ip, char *buf);
+dlm_stats_t my_dlmlock_sync(int mode, struct lockstatus *lksb, int
flags, 
+		struct opendlm_lock *lock, dlm_bastlockfunc_t * bast);
+
+
+/*Copy from linux 2.6*/
+/**
+ * container_of - cast a member of a structure out to the containing
structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+
+
+/* DEBUG utilities */
+
+extern int debug;
+
+#define dbg(format, arg...)						\
+        do {								\
+                if(debug)						\
+                        printk (KERN_DEBUG "%s %s: " format "\n",	\
+                                PROTO_NAME, __FUNCTION__, ## arg);	\
+        } while(0)
+
+
+#define err(format, arg...) \
+                printk(KERN_ERR "%s %s: " format "\n", \
+                       PROTO_NAME, __FUNCTION__ , ## arg)
+#define info(format, arg...) \
+                printk(KERN_INFO "%s %s: " format "\n", \
+                       PROTO_NAME, __FUNCTION__ , ## arg)
+#define warn(format, arg...) \
+                printk(KERN_WARNING "%s %s: " format "\n", \
+                      PROTO_NAME,  __FUNCTION__ , ## arg)
+#define trace(format, arg...) \
+                printk(KERN_INFO "%s %s(" format ")\n", \
+                       PROTO_NAME, __FUNCTION__ , ## arg)




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Opengfs-devel mailing list
Opengfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opengfs-devel

[Kernel]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Clusters]     [Linux RAID]     [Yosemite Hiking]     [Linux Resources]

Powered by Linux