Commit 869d81df authored by David Teigland's avatar David Teigland Committed by Steven Whitehouse
Browse files

[GFS2] An update of the GFS2 lock modules



This brings the lock modules uptodate and removes the stray
.mod.c file which accidently got included in the last check in.

Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent a8f2d647
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
obj-$(CONFIG_GFS2_FS) += lock_dlm.o
lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o
lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o
+52 −52
Original line number Diff line number Diff line
/******************************************************************************
*******************************************************************************
**
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
**
**  This copyrighted material is made available to anyone wishing to use,
**  modify, copy, or redistribute it subject to the terms and conditions
**  of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include "lock_dlm.h"

@@ -38,7 +34,7 @@ static inline void gdlm_bast(void *astarg, int mode)
	struct gdlm_ls *ls = lp->ls;

	if (!mode) {
		printk("lock_dlm: bast mode zero %x,%"PRIx64"\n",
		printk("lock_dlm: bast mode zero %x,%llx\n",
			lp->lockname.ln_type, lp->lockname.ln_number);
		return;
	}
@@ -75,9 +71,9 @@ static int16_t make_mode(int16_t lmstate)
		return DLM_LOCK_CW;
	case LM_ST_SHARED:
		return DLM_LOCK_PR;
	default:
		GDLM_ASSERT(0, printk("unknown LM state %d\n", lmstate););
	}
	gdlm_assert(0, "unknown LM state %d", lmstate);
	return -1;
}

/* convert dlm lock-mode to gfs lock-state */
@@ -94,9 +90,9 @@ int16_t gdlm_make_lmstate(int16_t dlmmode)
		return LM_ST_DEFERRED;
	case DLM_LOCK_PR:
		return LM_ST_SHARED;
	default:
		GDLM_ASSERT(0, printk("unknown DLM mode %d\n", dlmmode););
	}
	gdlm_assert(0, "unknown DLM mode %d", dlmmode);
	return -1;
}

/* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and
@@ -106,7 +102,7 @@ static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state)
{
	int16_t cur = make_mode(cur_state);
	if (lp->cur != DLM_LOCK_IV)
		GDLM_ASSERT(lp->cur == cur, printk("%d, %d\n", lp->cur, cur););
		gdlm_assert(lp->cur == cur, "%d, %d", lp->cur, cur);
}

static inline unsigned int make_flags(struct gdlm_lock *lp,
@@ -157,7 +153,7 @@ static inline unsigned int make_flags(struct gdlm_lock *lp,
static inline void make_strname(struct lm_lockname *lockname,
				struct gdlm_strname *str)
{
	sprintf(str->name, "%8x%16"PRIx64, lockname->ln_type,
	sprintf(str->name, "%8x%16llx", lockname->ln_type,
		lockname->ln_number);
	str->namelen = GDLM_STRNAME_BYTES;
}
@@ -167,11 +163,10 @@ int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name,
{
	struct gdlm_lock *lp;

	lp = kmalloc(sizeof(struct gdlm_lock), GFP_KERNEL);
	lp = kzalloc(sizeof(struct gdlm_lock), GFP_KERNEL);
	if (!lp)
		return -ENOMEM;

	memset(lp, 0, sizeof(struct gdlm_lock));
	lp->lockname = *name;
	lp->ls = ls;
	lp->cur = DLM_LOCK_IV;
@@ -202,7 +197,8 @@ void gdlm_delete_lp(struct gdlm_lock *lp)
		list_del_init(&lp->blist);
	if (!list_empty(&lp->delay_list))
		list_del_init(&lp->delay_list);
	GDLM_ASSERT(!list_empty(&lp->all_list),);
	gdlm_assert(!list_empty(&lp->all_list),
		    "%x,%llx", lp->lockname.ln_type, lp->lockname.ln_number);
	list_del_init(&lp->all_list);
	ls->all_locks_count--;
	spin_unlock(&ls->async_lock);
@@ -227,7 +223,7 @@ void gdlm_put_lock(lm_lock_t *lock)
	gdlm_delete_lp((struct gdlm_lock *) lock);
}

void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range)
unsigned int gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range)
{
	struct gdlm_ls *ls = lp->ls;
	struct gdlm_strname str;
@@ -242,7 +238,7 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range)
	if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) &&
	    !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) {
		gdlm_queue_delayed(lp);
		return;
		return LM_OUT_ASYNC;
	}

	/*
@@ -256,7 +252,7 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range)

	set_bit(LFL_ACTIVE, &lp->flags);

	log_debug("lk %x,%"PRIx64" id %x %d,%d %x", lp->lockname.ln_type,
	log_debug("lk %x,%llx id %x %d,%d %x", lp->lockname.ln_type,
		  lp->lockname.ln_number, lp->lksb.sb_lkid,
		  lp->cur, lp->req, lp->lkf);

@@ -270,15 +266,19 @@ void gdlm_do_lock(struct gdlm_lock *lp, struct dlm_range *range)
		error = 0;
	}

	GDLM_ASSERT(!error,
		   printk("%s: num=%x,%"PRIx64" err=%d cur=%d req=%d lkf=%x\n",
			  ls->fsname, lp->lockname.ln_type,
	if (error) {
		log_debug("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x "
			  "flags=%lx", ls->fsname, lp->lockname.ln_type,
			  lp->lockname.ln_number, error, lp->cur, lp->req,
			  lp->lkf););
			  lp->lkf, lp->flags);
		return LM_OUT_ERROR;
	}
	return LM_OUT_ASYNC;
}

void gdlm_do_unlock(struct gdlm_lock *lp)
unsigned int gdlm_do_unlock(struct gdlm_lock *lp)
{
	struct gdlm_ls *ls = lp->ls;
	unsigned int lkf = 0;
	int error;

@@ -288,16 +288,19 @@ void gdlm_do_unlock(struct gdlm_lock *lp)
	if (lp->lvb)
		lkf = DLM_LKF_VALBLK;

	log_debug("un %x,%"PRIx64" %x %d %x", lp->lockname.ln_type,
	log_debug("un %x,%llx %x %d %x", lp->lockname.ln_type,
		  lp->lockname.ln_number, lp->lksb.sb_lkid, lp->cur, lkf);

	error = dlm_unlock(lp->ls->dlm_lockspace, lp->lksb.sb_lkid, lkf,
			   NULL, lp);
	error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, NULL, lp);

	GDLM_ASSERT(!error,
		   printk("%s: error=%d num=%x,%"PRIx64" lkf=%x flags=%lx\n",
			  lp->ls->fsname, error, lp->lockname.ln_type,
			  lp->lockname.ln_number, lkf, lp->flags););
	if (error) {
		log_debug("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x "
			  "flags=%lx", ls->fsname, lp->lockname.ln_type,
			  lp->lockname.ln_number, error, lp->cur, lp->req,
			  lp->lkf, lp->flags);
		return LM_OUT_ERROR;
	}
	return LM_OUT_ASYNC;
}

unsigned int gdlm_lock(lm_lock_t *lock, unsigned int cur_state,
@@ -313,8 +316,7 @@ unsigned int gdlm_lock(lm_lock_t *lock, unsigned int cur_state,
	lp->req = make_mode(req_state);
	lp->lkf = make_flags(lp, flags, lp->cur, lp->req);

	gdlm_do_lock(lp, NULL);
	return LM_OUT_ASYNC;
	return gdlm_do_lock(lp, NULL);
}

unsigned int gdlm_unlock(lm_lock_t *lock, unsigned int cur_state)
@@ -324,8 +326,7 @@ unsigned int gdlm_unlock(lm_lock_t *lock, unsigned int cur_state)
	clear_bit(LFL_DLM_CANCEL, &lp->flags);
	if (lp->cur == DLM_LOCK_IV)
		return 0;
	gdlm_do_unlock(lp);
	return LM_OUT_ASYNC;
	return gdlm_do_unlock(lp);
}

void gdlm_cancel(lm_lock_t *lock)
@@ -337,7 +338,7 @@ void gdlm_cancel(lm_lock_t *lock)
	if (test_bit(LFL_DLM_CANCEL, &lp->flags))
		return;

	log_all("gdlm_cancel %x,%"PRIx64" flags %lx",
	log_info("gdlm_cancel %x,%llx flags %lx",
		 lp->lockname.ln_type, lp->lockname.ln_number, lp->flags);

	spin_lock(&ls->async_lock);
@@ -356,7 +357,7 @@ void gdlm_cancel(lm_lock_t *lock)

	if (!test_bit(LFL_ACTIVE, &lp->flags) ||
	    test_bit(LFL_DLM_UNLOCK, &lp->flags))	{
		log_all("gdlm_cancel skip %x,%"PRIx64" flags %lx",
		log_info("gdlm_cancel skip %x,%llx flags %lx",
		 	 lp->lockname.ln_type, lp->lockname.ln_number,
			 lp->flags);
		return;
@@ -370,7 +371,7 @@ void gdlm_cancel(lm_lock_t *lock)
	error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, DLM_LKF_CANCEL,
			   NULL, lp);

	log_all("gdlm_cancel rv %d %x,%"PRIx64" flags %lx", error,
	log_info("gdlm_cancel rv %d %x,%llx flags %lx", error,
		 lp->lockname.ln_type, lp->lockname.ln_number, lp->flags);

	if (error == -EBUSY)
@@ -381,12 +382,10 @@ int gdlm_add_lvb(struct gdlm_lock *lp)
{
	char *lvb;

	lvb = kmalloc(GDLM_LVB_SIZE, GFP_KERNEL);
	lvb = kzalloc(GDLM_LVB_SIZE, GFP_KERNEL);
	if (!lvb)
		return -ENOMEM;

	memset(lvb, 0, GDLM_LVB_SIZE);

	lp->lksb.sb_lvbptr = lvb;
	lp->lvb = lvb;
	return 0;
@@ -448,7 +447,8 @@ static void unhold_null_lock(struct gdlm_lock *lp)
{
	struct gdlm_lock *lpn = lp->hold_null;

	GDLM_ASSERT(lpn,);
	gdlm_assert(lpn, "%x,%llx",
		    lp->lockname.ln_type, lp->lockname.ln_number);
	lpn->lksb.sb_lvbptr = NULL;
	lpn->lvb = NULL;
	set_bit(LFL_UNLOCK_DELETE, &lpn->flags);
+191 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#ifndef LOCK_DLM_DOT_H
#define LOCK_DLM_DOT_H

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/socket.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/kobject.h>
#include <linux/fcntl.h>
#include <linux/wait.h>
#include <net/sock.h>

#include <linux/dlm.h>
#include "../../lm_interface.h"

/*
 * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a
 * prefix of lock_dlm_ gets awkward.  Externally, GFS refers to this module
 * as "lock_dlm".
 */

#define GDLM_STRNAME_BYTES	24
#define GDLM_LVB_SIZE		32
#define GDLM_DROP_COUNT		50000
#define GDLM_DROP_PERIOD	60
#define GDLM_NAME_LEN		128

/* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number).
   We sprintf these numbers into a 24 byte string of hex values to make them
   human-readable (to make debugging simpler.) */

struct gdlm_strname {
	unsigned char		name[GDLM_STRNAME_BYTES];
	unsigned short		namelen;
};

enum {
	DFL_BLOCK_LOCKS		= 0,
	DFL_SPECTATOR		= 1,
	DFL_WITHDRAW		= 2,
};

struct gdlm_ls {
	uint32_t		id;
	int			jid;
	int			first;
	int			first_done;
	unsigned long		flags;
	struct kobject		kobj;
	char			clustername[GDLM_NAME_LEN];
	char			fsname[GDLM_NAME_LEN];
	int			fsflags;
	dlm_lockspace_t		*dlm_lockspace;
	lm_callback_t		fscb;
	lm_fsdata_t		*fsdata;
	int			recover_jid;
	int			recover_jid_done;
	spinlock_t		async_lock;
	struct list_head	complete;
	struct list_head	blocking;
	struct list_head	delayed;
	struct list_head	submit;
	struct list_head	all_locks;
	uint32_t		all_locks_count;
	wait_queue_head_t	wait_control;
	struct task_struct	*thread1;
	struct task_struct	*thread2;
	wait_queue_head_t	thread_wait;
	unsigned long		drop_time;
	int			drop_locks_count;
	int			drop_locks_period;
};

enum {
	LFL_NOBLOCK		= 0,
	LFL_NOCACHE		= 1,
	LFL_DLM_UNLOCK		= 2,
	LFL_DLM_CANCEL		= 3,
	LFL_SYNC_LVB		= 4,
	LFL_FORCE_PROMOTE	= 5,
	LFL_REREQUEST		= 6,
	LFL_ACTIVE		= 7,
	LFL_INLOCK		= 8,
	LFL_CANCEL		= 9,
	LFL_NOBAST		= 10,
	LFL_HEADQUE		= 11,
	LFL_UNLOCK_DELETE	= 12,
};

struct gdlm_lock {
	struct gdlm_ls		*ls;
	struct lm_lockname	lockname;
	char			*lvb;
	struct dlm_lksb		lksb;

	int16_t			cur;
	int16_t			req;
	int16_t			prev_req;
	uint32_t		lkf;		/* dlm flags DLM_LKF_ */
	unsigned long		flags;		/* lock_dlm flags LFL_ */

	int			bast_mode;	/* protected by async_lock */
	struct completion	ast_wait;

	struct list_head	clist;		/* complete */
	struct list_head	blist;		/* blocking */
	struct list_head	delay_list;	/* delayed */
	struct list_head	all_list;	/* all locks for the fs */
	struct gdlm_lock	*hold_null;	/* NL lock for hold_lvb */
};

#define gdlm_assert(assertion, fmt, args...)                                  \
do {                                                                          \
	if (unlikely(!(assertion))) {                                         \
		printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \
				  "lock_dlm:  " fmt "\n",                     \
				  #assertion, ##args);                        \
		BUG();                                                        \
	}                                                                     \
} while (0)

#define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg)
#define log_info(fmt, arg...)  log_print(KERN_INFO , fmt , ## arg)
#define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg)
#ifdef LOCK_DLM_LOG_DEBUG
#define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg)
#else
#define log_debug(fmt, arg...)
#endif

/* sysfs.c */

int gdlm_sysfs_init(void);
void gdlm_sysfs_exit(void);
int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *);
void gdlm_kobject_release(struct gdlm_ls *);

/* thread.c */

int gdlm_init_threads(struct gdlm_ls *);
void gdlm_release_threads(struct gdlm_ls *);

/* lock.c */

int16_t gdlm_make_lmstate(int16_t);
void gdlm_queue_delayed(struct gdlm_lock *);
void gdlm_submit_delayed(struct gdlm_ls *);
int gdlm_release_all_locks(struct gdlm_ls *);
int gdlm_create_lp(struct gdlm_ls *, struct lm_lockname *, struct gdlm_lock **);
void gdlm_delete_lp(struct gdlm_lock *);
int gdlm_add_lvb(struct gdlm_lock *);
void gdlm_del_lvb(struct gdlm_lock *);
unsigned int gdlm_do_lock(struct gdlm_lock *, struct dlm_range *);
unsigned int gdlm_do_unlock(struct gdlm_lock *);

int gdlm_get_lock(lm_lockspace_t *, struct lm_lockname *, lm_lock_t **);
void gdlm_put_lock(lm_lock_t *);
unsigned int gdlm_lock(lm_lock_t *, unsigned int, unsigned int, unsigned int);
unsigned int gdlm_unlock(lm_lock_t *, unsigned int);
void gdlm_cancel(lm_lock_t *);
int gdlm_hold_lvb(lm_lock_t *, char **);
void gdlm_unhold_lvb(lm_lock_t *, char *);
void gdlm_sync_lvb(lm_lock_t *, char *);

/* plock.c */

int gdlm_plock_init(void);
void gdlm_plock_exit(void);
int gdlm_plock(lm_lockspace_t *, struct lm_lockname *, struct file *, int,
		struct file_lock *);
int gdlm_plock_get(lm_lockspace_t *, struct lm_lockname *, struct file *,
		struct file_lock *);
int gdlm_punlock(lm_lockspace_t *, struct lm_lockname *, struct file *,
		struct file_lock *);
#endif
+19 −15
Original line number Diff line number Diff line
/******************************************************************************
*******************************************************************************
**
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
**
**  This copyrighted material is made available to anyone wishing to use,
**  modify, copy, or redistribute it subject to the terms and conditions
**  of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include <linux/init.h>

@@ -24,7 +20,7 @@ int __init init_lock_dlm(void)
{
	int error;

	error = lm_register_proto(&gdlm_ops);
	error = gfs_register_lockproto(&gdlm_ops);
	if (error) {
		printk("lock_dlm:  can't register protocol: %d\n", error);
		return error;
@@ -32,7 +28,14 @@ int __init init_lock_dlm(void)

	error = gdlm_sysfs_init();
	if (error) {
		lm_unregister_proto(&gdlm_ops);
		gfs_unregister_lockproto(&gdlm_ops);
		return error;
	}

	error = gdlm_plock_init();
	if (error) {
		gdlm_sysfs_exit();
		gfs_unregister_lockproto(&gdlm_ops);
		return error;
	}

@@ -45,8 +48,9 @@ int __init init_lock_dlm(void)

void __exit exit_lock_dlm(void)
{
	lm_unregister_proto(&gdlm_ops);
	gdlm_plock_exit();
	gdlm_sysfs_exit();
	gfs_unregister_lockproto(&gdlm_ops);
}

module_init(init_lock_dlm);
+98 −91
Original line number Diff line number Diff line
/******************************************************************************
*******************************************************************************
**
**  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
**  Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
**
**  This copyrighted material is made available to anyone wishing to use,
**  modify, copy, or redistribute it subject to the terms and conditions
**  of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include "lock_dlm.h"

@@ -24,27 +20,21 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,
	struct gdlm_ls *ls;
	char buf[256], *p;

	ls = kmalloc(sizeof(struct gdlm_ls), GFP_KERNEL);
	ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL);
	if (!ls)
		return NULL;

	memset(ls, 0, sizeof(struct gdlm_ls));

	ls->drop_locks_count = gdlm_drop_count;
	ls->drop_locks_period = gdlm_drop_period;

	ls->fscb = cb;
	ls->fsdata = fsdata;
	ls->fsflags = flags;

	spin_lock_init(&ls->async_lock);

	INIT_LIST_HEAD(&ls->complete);
	INIT_LIST_HEAD(&ls->blocking);
	INIT_LIST_HEAD(&ls->delayed);
	INIT_LIST_HEAD(&ls->submit);
	INIT_LIST_HEAD(&ls->all_locks);

	init_waitqueue_head(&ls->thread_wait);
	init_waitqueue_head(&ls->wait_control);
	ls->thread1 = NULL;
@@ -57,23 +47,75 @@ static struct gdlm_ls *init_gdlm(lm_callback_t cb, lm_fsdata_t *fsdata,

	p = strstr(buf, ":");
	if (!p) {
		printk("lock_dlm: invalid table_name \"%s\"\n", table_name);
		log_info("invalid table_name \"%s\"", table_name);
		kfree(ls);
		return NULL;
	}
	*p = '\0';
	p++;

	strncpy(ls->clustername, buf, 128);
	strncpy(ls->fsname, p, 128);
	strncpy(ls->clustername, buf, GDLM_NAME_LEN);
	strncpy(ls->fsname, p, GDLM_NAME_LEN);

	return ls;
}

static int make_args(struct gdlm_ls *ls, char *data_arg)
{
	char data[256];
	char *options, *x, *y;
	int error = 0;

	memset(data, 0, 256);
	strncpy(data, data_arg, 255);

	for (options = data; (x = strsep(&options, ":")); ) {
		if (!*x)
			continue;

		y = strchr(x, '=');
		if (y)
			*y++ = 0;

		if (!strcmp(x, "jid")) {
			if (!y) {
				log_error("need argument to jid");
				error = -EINVAL;
				break;
			}
			sscanf(y, "%u", &ls->jid);

		} else if (!strcmp(x, "first")) {
			if (!y) {
				log_error("need argument to first");
				error = -EINVAL;
				break;
			}
			sscanf(y, "%u", &ls->first);

		} else if (!strcmp(x, "id")) {
			if (!y) {
				log_error("need argument to id");
				error = -EINVAL;
				break;
			}
			sscanf(y, "%u", &ls->id);

		} else {
			log_error("unkonwn option: %s", x);
			error = -EINVAL;
			break;
		}
	}

	return error;
}

static int gdlm_mount(char *table_name, char *host_data,
			lm_callback_t cb, lm_fsdata_t *fsdata,
			unsigned int min_lvb_size, int flags,
			struct lm_lockstruct *lockstruct)
			struct lm_lockstruct *lockstruct,
			struct kobject *fskobj)
{
	struct gdlm_ls *ls;
	int error = -ENOMEM;
@@ -92,30 +134,18 @@ static int gdlm_mount(char *table_name, char *host_data,
	error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname),
				  &ls->dlm_lockspace, 0, GDLM_LVB_SIZE);
	if (error) {
		printk("lock_dlm: dlm_new_lockspace error %d\n", error);
		log_error("dlm_new_lockspace error %d", error);
		goto out_thread;
	}

	error = gdlm_kobject_setup(ls);
	error = gdlm_kobject_setup(ls, fskobj);
	if (error)
		goto out_dlm;
	kobject_uevent(&ls->kobj, KOBJ_MOUNT, NULL);

	/* Now we depend on userspace to notice the new mount,
	   join the appropriate group, and do a write to our sysfs
	   "mounted" or "terminate" file.  Before the start, userspace
	   must set "jid" and "first". */

	error = wait_event_interruptible(ls->wait_control,
			test_bit(DFL_JOIN_DONE, &ls->flags));
	error = make_args(ls, host_data);
	if (error)
		goto out_sysfs;

	if (test_bit(DFL_TERMINATE, &ls->flags)) {
		error = -ERESTARTSYS;
		goto out_sysfs;
	}

	lockstruct->ls_jid = ls->jid;
	lockstruct->ls_first = ls->first;
	lockstruct->ls_lockspace = ls;
@@ -143,22 +173,19 @@ static void gdlm_unmount(lm_lockspace_t *lockspace)

	log_debug("unmount flags %lx", ls->flags);

	if (test_bit(DFL_WITHDRAW, &ls->flags)) {
		gdlm_kobject_release(ls);
		goto out;
	}

	kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);
	/* FIXME: serialize unmount and withdraw in case they
	   happen at once.  Also, if unmount follows withdraw,
	   wait for withdraw to finish. */

	wait_event_interruptible(ls->wait_control,
				 test_bit(DFL_LEAVE_DONE, &ls->flags));
	if (test_bit(DFL_WITHDRAW, &ls->flags))
		goto out;

	gdlm_kobject_release(ls);
	dlm_release_lockspace(ls->dlm_lockspace, 2);
	gdlm_release_threads(ls);
	rv = gdlm_release_all_locks(ls);
	if (rv)
		log_all("lm_dlm_unmount: %d stray locks freed", rv);
		log_info("gdlm_unmount: %d stray locks freed", rv);
 out:
	kfree(ls);
}
@@ -167,7 +194,7 @@ static void gdlm_recovery_done(lm_lockspace_t *lockspace, unsigned int jid,
                               unsigned int message)
{
	struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;
	ls->recover_done = jid;
	ls->recover_jid_done = jid;
	kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
}

@@ -178,12 +205,14 @@ static void gdlm_others_may_mount(lm_lockspace_t *lockspace)
	kobject_uevent(&ls->kobj, KOBJ_CHANGE, NULL);
}

/* Userspace gets the offline uevent, blocks new gfs locks on
   other mounters, and lets us know (sets WITHDRAW flag).  Then,
   userspace leaves the mount group while we leave the lockspace. */

static void gdlm_withdraw(lm_lockspace_t *lockspace)
{
	struct gdlm_ls *ls = (struct gdlm_ls *) lockspace;

	/* userspace suspends locking on all other members */

	kobject_uevent(&ls->kobj, KOBJ_OFFLINE, NULL);

	wait_event_interruptible(ls->wait_control,
@@ -192,49 +221,27 @@ static void gdlm_withdraw(lm_lockspace_t *lockspace)
	dlm_release_lockspace(ls->dlm_lockspace, 2);
	gdlm_release_threads(ls);
	gdlm_release_all_locks(ls);

	kobject_uevent(&ls->kobj, KOBJ_UMOUNT, NULL);

	/* userspace leaves the mount group, we don't need to wait for
	   that to complete */
}

int gdlm_plock_get(lm_lockspace_t *lockspace, struct lm_lockname *name,
		   struct file *file, struct file_lock *fl)
{
	return -ENOSYS;
}

int gdlm_punlock(lm_lockspace_t *lockspace, struct lm_lockname *name,
		   struct file *file, struct file_lock *fl)
{
	return -ENOSYS;
}

int gdlm_plock(lm_lockspace_t *lockspace, struct lm_lockname *name,
	       struct file *file, int cmd, struct file_lock *fl)
{
	return -ENOSYS;
	gdlm_kobject_release(ls);
}

struct lm_lockops gdlm_ops = {
	lm_proto_name:"lock_dlm",
	lm_mount:gdlm_mount,
	lm_others_may_mount:gdlm_others_may_mount,
	lm_unmount:gdlm_unmount,
	lm_withdraw:gdlm_withdraw,
	lm_get_lock:gdlm_get_lock,
	lm_put_lock:gdlm_put_lock,
	lm_lock:gdlm_lock,
	lm_unlock:gdlm_unlock,
	lm_plock:gdlm_plock,
	lm_punlock:gdlm_punlock,
	lm_plock_get:gdlm_plock_get,
	lm_cancel:gdlm_cancel,
	lm_hold_lvb:gdlm_hold_lvb,
	lm_unhold_lvb:gdlm_unhold_lvb,
	lm_sync_lvb:gdlm_sync_lvb,
	lm_recovery_done:gdlm_recovery_done,
	lm_owner:THIS_MODULE,
	.lm_proto_name = "lock_dlm",
	.lm_mount = gdlm_mount,
	.lm_others_may_mount = gdlm_others_may_mount,
	.lm_unmount = gdlm_unmount,
	.lm_withdraw = gdlm_withdraw,
	.lm_get_lock = gdlm_get_lock,
	.lm_put_lock = gdlm_put_lock,
	.lm_lock = gdlm_lock,
	.lm_unlock = gdlm_unlock,
	.lm_plock = gdlm_plock,
	.lm_punlock = gdlm_punlock,
	.lm_plock_get = gdlm_plock_get,
	.lm_cancel = gdlm_cancel,
	.lm_hold_lvb = gdlm_hold_lvb,
	.lm_unhold_lvb = gdlm_unhold_lvb,
	.lm_sync_lvb = gdlm_sync_lvb,
	.lm_recovery_done = gdlm_recovery_done,
	.lm_owner = THIS_MODULE,
};
Loading