Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm:
  dlm: linux/{dlm,dlm_device}.h: cleanup for userspace
  dlm: common max length definitions
  dlm: move plock code from gfs2
  dlm: recover nodes that are removed and re-added
  dlm: save master info after failed no-queue request
  dlm: make dlm_print_rsb() static
  dlm: match signedness between dlm_config_info and cluster_set
This commit is contained in:
Linus Torvalds 2008-04-22 13:44:23 -07:00
commit 03b883840c
20 changed files with 277 additions and 162 deletions

View File

@ -10,6 +10,7 @@ dlm-y := ast.o \
midcomms.o \ midcomms.o \
netlink.o \ netlink.o \
lowcomms.o \ lowcomms.o \
plock.o \
rcom.o \ rcom.o \
recover.o \ recover.o \
recoverd.o \ recoverd.o \

View File

@ -114,7 +114,7 @@ struct cluster_attribute {
}; };
static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field, static ssize_t cluster_set(struct cluster *cl, unsigned int *cl_field,
unsigned int *info_field, int check_zero, int *info_field, int check_zero,
const char *buf, size_t len) const char *buf, size_t len)
{ {
unsigned int x; unsigned int x;
@ -284,6 +284,7 @@ struct node {
struct list_head list; /* space->members */ struct list_head list; /* space->members */
int nodeid; int nodeid;
int weight; int weight;
int new;
}; };
static struct configfs_group_operations clusters_ops = { static struct configfs_group_operations clusters_ops = {
@ -565,6 +566,7 @@ static struct config_item *make_node(struct config_group *g, const char *name)
config_item_init_type_name(&nd->item, name, &node_type); config_item_init_type_name(&nd->item, name, &node_type);
nd->nodeid = -1; nd->nodeid = -1;
nd->weight = 1; /* default weight of 1 if none is set */ nd->weight = 1; /* default weight of 1 if none is set */
nd->new = 1; /* set to 0 once it's been read by dlm_nodeid_list() */
mutex_lock(&sp->members_lock); mutex_lock(&sp->members_lock);
list_add(&nd->list, &sp->members); list_add(&nd->list, &sp->members);
@ -805,12 +807,13 @@ static void put_comm(struct comm *cm)
} }
/* caller must free mem */ /* caller must free mem */
int dlm_nodeid_list(char *lsname, int **ids_out) int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
int **new_out, int *new_count_out)
{ {
struct space *sp; struct space *sp;
struct node *nd; struct node *nd;
int i = 0, rv = 0; int i = 0, rv = 0, ids_count = 0, new_count = 0;
int *ids; int *ids, *new;
sp = get_space(lsname); sp = get_space(lsname);
if (!sp) if (!sp)
@ -818,23 +821,50 @@ int dlm_nodeid_list(char *lsname, int **ids_out)
mutex_lock(&sp->members_lock); mutex_lock(&sp->members_lock);
if (!sp->members_count) { if (!sp->members_count) {
rv = 0; rv = -EINVAL;
printk(KERN_ERR "dlm: zero members_count\n");
goto out; goto out;
} }
ids = kcalloc(sp->members_count, sizeof(int), GFP_KERNEL); ids_count = sp->members_count;
ids = kcalloc(ids_count, sizeof(int), GFP_KERNEL);
if (!ids) { if (!ids) {
rv = -ENOMEM; rv = -ENOMEM;
goto out; goto out;
} }
rv = sp->members_count; list_for_each_entry(nd, &sp->members, list) {
list_for_each_entry(nd, &sp->members, list)
ids[i++] = nd->nodeid; ids[i++] = nd->nodeid;
if (nd->new)
new_count++;
}
if (rv != i) if (ids_count != i)
printk("bad nodeid count %d %d\n", rv, i); printk(KERN_ERR "dlm: bad nodeid count %d %d\n", ids_count, i);
if (!new_count)
goto out_ids;
new = kcalloc(new_count, sizeof(int), GFP_KERNEL);
if (!new) {
kfree(ids);
rv = -ENOMEM;
goto out;
}
i = 0;
list_for_each_entry(nd, &sp->members, list) {
if (nd->new) {
new[i++] = nd->nodeid;
nd->new = 0;
}
}
*new_count_out = new_count;
*new_out = new;
out_ids:
*ids_count_out = ids_count;
*ids_out = ids; *ids_out = ids;
out: out:
mutex_unlock(&sp->members_lock); mutex_unlock(&sp->members_lock);

View File

@ -35,7 +35,8 @@ extern struct dlm_config_info dlm_config;
int dlm_config_init(void); int dlm_config_init(void);
void dlm_config_exit(void); void dlm_config_exit(void);
int dlm_node_weight(char *lsname, int nodeid); int dlm_node_weight(char *lsname, int nodeid);
int dlm_nodeid_list(char *lsname, int **ids_out); int dlm_nodeid_list(char *lsname, int **ids_out, int *ids_count_out,
int **new_out, int *new_count_out);
int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr); int dlm_nodeid_to_addr(int nodeid, struct sockaddr_storage *addr);
int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid); int dlm_addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid);
int dlm_our_nodeid(void); int dlm_our_nodeid(void);

View File

@ -42,8 +42,6 @@
#include <linux/dlm.h> #include <linux/dlm.h>
#include "config.h" #include "config.h"
#define DLM_LOCKSPACE_LEN 64
/* Size of the temp buffer midcomms allocates on the stack. /* Size of the temp buffer midcomms allocates on the stack.
We try to make this large enough so most messages fit. We try to make this large enough so most messages fit.
FIXME: should sctp make this unnecessary? */ FIXME: should sctp make this unnecessary? */
@ -132,8 +130,10 @@ struct dlm_member {
struct dlm_recover { struct dlm_recover {
struct list_head list; struct list_head list;
int *nodeids; int *nodeids; /* nodeids of all members */
int node_count; int node_count;
int *new; /* nodeids of new members */
int new_count;
uint64_t seq; uint64_t seq;
}; };
@ -579,6 +579,8 @@ static inline int dlm_no_directory(struct dlm_ls *ls)
int dlm_netlink_init(void); int dlm_netlink_init(void);
void dlm_netlink_exit(void); void dlm_netlink_exit(void);
void dlm_timeout_warn(struct dlm_lkb *lkb); void dlm_timeout_warn(struct dlm_lkb *lkb);
int dlm_plock_init(void);
void dlm_plock_exit(void);
#ifdef CONFIG_DLM_DEBUG #ifdef CONFIG_DLM_DEBUG
int dlm_register_debugfs(void); int dlm_register_debugfs(void);

View File

@ -165,7 +165,7 @@ void dlm_print_lkb(struct dlm_lkb *lkb)
lkb->lkb_grmode, lkb->lkb_wait_type, lkb->lkb_ast_type); lkb->lkb_grmode, lkb->lkb_wait_type, lkb->lkb_ast_type);
} }
void dlm_print_rsb(struct dlm_rsb *r) static void dlm_print_rsb(struct dlm_rsb *r)
{ {
printk(KERN_ERR "rsb: nodeid %d flags %lx first %x rlc %d name %s\n", printk(KERN_ERR "rsb: nodeid %d flags %lx first %x rlc %d name %s\n",
r->res_nodeid, r->res_flags, r->res_first_lkid, r->res_nodeid, r->res_flags, r->res_first_lkid,
@ -1956,8 +1956,7 @@ static void confirm_master(struct dlm_rsb *r, int error)
list_del_init(&lkb->lkb_rsb_lookup); list_del_init(&lkb->lkb_rsb_lookup);
r->res_first_lkid = lkb->lkb_id; r->res_first_lkid = lkb->lkb_id;
_request_lock(r, lkb); _request_lock(r, lkb);
} else }
r->res_nodeid = -1;
break; break;
default: default:

View File

@ -13,7 +13,6 @@
#ifndef __LOCK_DOT_H__ #ifndef __LOCK_DOT_H__
#define __LOCK_DOT_H__ #define __LOCK_DOT_H__
void dlm_print_rsb(struct dlm_rsb *r);
void dlm_dump_rsb(struct dlm_rsb *r); void dlm_dump_rsb(struct dlm_rsb *r);
void dlm_print_lkb(struct dlm_lkb *lkb); void dlm_print_lkb(struct dlm_lkb *lkb);
void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms); void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);

View File

@ -46,10 +46,16 @@ static int __init init_dlm(void)
if (error) if (error)
goto out_user; goto out_user;
error = dlm_plock_init();
if (error)
goto out_netlink;
printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); printk("DLM (built %s %s) installed\n", __DATE__, __TIME__);
return 0; return 0;
out_netlink:
dlm_netlink_exit();
out_user: out_user:
dlm_user_exit(); dlm_user_exit();
out_debug: out_debug:
@ -66,6 +72,7 @@ static int __init init_dlm(void)
static void __exit exit_dlm(void) static void __exit exit_dlm(void)
{ {
dlm_plock_exit();
dlm_netlink_exit(); dlm_netlink_exit();
dlm_user_exit(); dlm_user_exit();
dlm_config_exit(); dlm_config_exit();

View File

@ -210,6 +210,23 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
} }
} }
/* Add an entry to ls_nodes_gone for members that were removed and
then added again, so that previous state for these nodes will be
cleared during recovery. */
for (i = 0; i < rv->new_count; i++) {
if (!dlm_is_member(ls, rv->new[i]))
continue;
log_debug(ls, "new nodeid %d is a re-added member", rv->new[i]);
memb = kzalloc(sizeof(struct dlm_member), GFP_KERNEL);
if (!memb)
return -ENOMEM;
memb->nodeid = rv->new[i];
list_add_tail(&memb->list, &ls->ls_nodes_gone);
neg++;
}
/* add new members to ls_nodes */ /* add new members to ls_nodes */
for (i = 0; i < rv->node_count; i++) { for (i = 0; i < rv->node_count; i++) {
@ -314,15 +331,16 @@ int dlm_ls_stop(struct dlm_ls *ls)
int dlm_ls_start(struct dlm_ls *ls) int dlm_ls_start(struct dlm_ls *ls)
{ {
struct dlm_recover *rv = NULL, *rv_old; struct dlm_recover *rv = NULL, *rv_old;
int *ids = NULL; int *ids = NULL, *new = NULL;
int error, count; int error, ids_count = 0, new_count = 0;
rv = kzalloc(sizeof(struct dlm_recover), GFP_KERNEL); rv = kzalloc(sizeof(struct dlm_recover), GFP_KERNEL);
if (!rv) if (!rv)
return -ENOMEM; return -ENOMEM;
error = count = dlm_nodeid_list(ls->ls_name, &ids); error = dlm_nodeid_list(ls->ls_name, &ids, &ids_count,
if (error <= 0) &new, &new_count);
if (error < 0)
goto fail; goto fail;
spin_lock(&ls->ls_recover_lock); spin_lock(&ls->ls_recover_lock);
@ -337,14 +355,19 @@ int dlm_ls_start(struct dlm_ls *ls)
} }
rv->nodeids = ids; rv->nodeids = ids;
rv->node_count = count; rv->node_count = ids_count;
rv->new = new;
rv->new_count = new_count;
rv->seq = ++ls->ls_recover_seq; rv->seq = ++ls->ls_recover_seq;
rv_old = ls->ls_recover_args; rv_old = ls->ls_recover_args;
ls->ls_recover_args = rv; ls->ls_recover_args = rv;
spin_unlock(&ls->ls_recover_lock); spin_unlock(&ls->ls_recover_lock);
if (rv_old) { if (rv_old) {
log_error(ls, "unused recovery %llx %d",
(unsigned long long)rv_old->seq, rv_old->node_count);
kfree(rv_old->nodeids); kfree(rv_old->nodeids);
kfree(rv_old->new);
kfree(rv_old); kfree(rv_old);
} }
@ -354,6 +377,7 @@ int dlm_ls_start(struct dlm_ls *ls)
fail: fail:
kfree(rv); kfree(rv);
kfree(ids); kfree(ids);
kfree(new);
return error; return error;
} }

View File

@ -1,17 +1,19 @@
/* /*
* Copyright (C) 2005 Red Hat, Inc. All rights reserved. * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
* *
* This copyrighted material is made available to anyone wishing to use, * This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions * modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2. * of the GNU General Public License version 2.
*/ */
#include <linux/fs.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/lock_dlm_plock.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/dlm.h>
#include <linux/dlm_plock.h>
#include "lock_dlm.h" #include "dlm_internal.h"
#include "lockspace.h"
static spinlock_t ops_lock; static spinlock_t ops_lock;
static struct list_head send_list; static struct list_head send_list;
@ -22,7 +24,7 @@ static wait_queue_head_t recv_wq;
struct plock_op { struct plock_op {
struct list_head list; struct list_head list;
int done; int done;
struct gdlm_plock_info info; struct dlm_plock_info info;
}; };
struct plock_xop { struct plock_xop {
@ -34,22 +36,22 @@ struct plock_xop {
}; };
static inline void set_version(struct gdlm_plock_info *info) static inline void set_version(struct dlm_plock_info *info)
{ {
info->version[0] = GDLM_PLOCK_VERSION_MAJOR; info->version[0] = DLM_PLOCK_VERSION_MAJOR;
info->version[1] = GDLM_PLOCK_VERSION_MINOR; info->version[1] = DLM_PLOCK_VERSION_MINOR;
info->version[2] = GDLM_PLOCK_VERSION_PATCH; info->version[2] = DLM_PLOCK_VERSION_PATCH;
} }
static int check_version(struct gdlm_plock_info *info) static int check_version(struct dlm_plock_info *info)
{ {
if ((GDLM_PLOCK_VERSION_MAJOR != info->version[0]) || if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) ||
(GDLM_PLOCK_VERSION_MINOR < info->version[1])) { (DLM_PLOCK_VERSION_MINOR < info->version[1])) {
log_error("plock device version mismatch: " log_print("plock device version mismatch: "
"kernel (%u.%u.%u), user (%u.%u.%u)", "kernel (%u.%u.%u), user (%u.%u.%u)",
GDLM_PLOCK_VERSION_MAJOR, DLM_PLOCK_VERSION_MAJOR,
GDLM_PLOCK_VERSION_MINOR, DLM_PLOCK_VERSION_MINOR,
GDLM_PLOCK_VERSION_PATCH, DLM_PLOCK_VERSION_PATCH,
info->version[0], info->version[0],
info->version[1], info->version[1],
info->version[2]); info->version[2]);
@ -68,25 +70,31 @@ static void send_op(struct plock_op *op)
wake_up(&send_wq); wake_up(&send_wq);
} }
int gdlm_plock(void *lockspace, struct lm_lockname *name, int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file *file, int cmd, struct file_lock *fl) int cmd, struct file_lock *fl)
{ {
struct gdlm_ls *ls = lockspace; struct dlm_ls *ls;
struct plock_op *op; struct plock_op *op;
struct plock_xop *xop; struct plock_xop *xop;
int rv; int rv;
ls = dlm_find_lockspace_local(lockspace);
if (!ls)
return -EINVAL;
xop = kzalloc(sizeof(*xop), GFP_KERNEL); xop = kzalloc(sizeof(*xop), GFP_KERNEL);
if (!xop) if (!xop) {
return -ENOMEM; rv = -ENOMEM;
goto out;
}
op = &xop->xop; op = &xop->xop;
op->info.optype = GDLM_PLOCK_OP_LOCK; op->info.optype = DLM_PLOCK_OP_LOCK;
op->info.pid = fl->fl_pid; op->info.pid = fl->fl_pid;
op->info.ex = (fl->fl_type == F_WRLCK); op->info.ex = (fl->fl_type == F_WRLCK);
op->info.wait = IS_SETLKW(cmd); op->info.wait = IS_SETLKW(cmd);
op->info.fsid = ls->id; op->info.fsid = ls->ls_global_id;
op->info.number = name->ln_number; op->info.number = number;
op->info.start = fl->fl_start; op->info.start = fl->fl_start;
op->info.end = fl->fl_end; op->info.end = fl->fl_end;
if (fl->fl_lmops && fl->fl_lmops->fl_grant) { if (fl->fl_lmops && fl->fl_lmops->fl_grant) {
@ -107,12 +115,15 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
if (xop->callback == NULL) if (xop->callback == NULL)
wait_event(recv_wq, (op->done != 0)); wait_event(recv_wq, (op->done != 0));
else else {
return -EINPROGRESS; rv = -EINPROGRESS;
goto out;
}
spin_lock(&ops_lock); spin_lock(&ops_lock);
if (!list_empty(&op->list)) { if (!list_empty(&op->list)) {
printk(KERN_INFO "plock op on list\n"); log_error(ls, "dlm_posix_lock: op on list %llx",
(unsigned long long)number);
list_del(&op->list); list_del(&op->list);
} }
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
@ -121,17 +132,19 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
if (!rv) { if (!rv) {
if (posix_lock_file_wait(file, fl) < 0) if (posix_lock_file_wait(file, fl) < 0)
log_error("gdlm_plock: vfs lock error %x,%llx", log_error(ls, "dlm_posix_lock: vfs lock error %llx",
name->ln_type, (unsigned long long)number);
(unsigned long long)name->ln_number);
} }
kfree(xop); kfree(xop);
out:
dlm_put_lockspace(ls);
return rv; return rv;
} }
EXPORT_SYMBOL_GPL(dlm_posix_lock);
/* Returns failure iff a succesful lock operation should be canceled */ /* Returns failure iff a succesful lock operation should be canceled */
static int gdlm_plock_callback(struct plock_op *op) static int dlm_plock_callback(struct plock_op *op)
{ {
struct file *file; struct file *file;
struct file_lock *fl; struct file_lock *fl;
@ -142,7 +155,8 @@ static int gdlm_plock_callback(struct plock_op *op)
spin_lock(&ops_lock); spin_lock(&ops_lock);
if (!list_empty(&op->list)) { if (!list_empty(&op->list)) {
printk(KERN_INFO "plock op on list\n"); log_print("dlm_plock_callback: op on list %llx",
(unsigned long long)op->info.number);
list_del(&op->list); list_del(&op->list);
} }
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
@ -165,19 +179,19 @@ static int gdlm_plock_callback(struct plock_op *op)
* This can only happen in the case of kmalloc() failure. * This can only happen in the case of kmalloc() failure.
* The filesystem's own lock is the authoritative lock, * The filesystem's own lock is the authoritative lock,
* so a failure to get the lock locally is not a disaster. * so a failure to get the lock locally is not a disaster.
* As long as GFS cannot reliably cancel locks (especially * As long as the fs cannot reliably cancel locks (especially
* in a low-memory situation), we're better off ignoring * in a low-memory situation), we're better off ignoring
* this failure than trying to recover. * this failure than trying to recover.
*/ */
log_error("gdlm_plock: vfs lock error file %p fl %p", log_print("dlm_plock_callback: vfs lock error %llx file %p fl %p",
file, fl); (unsigned long long)op->info.number, file, fl);
} }
rv = notify(flc, NULL, 0); rv = notify(flc, NULL, 0);
if (rv) { if (rv) {
/* XXX: We need to cancel the fs lock here: */ /* XXX: We need to cancel the fs lock here: */
printk("gfs2 lock granted after lock request failed;" log_print("dlm_plock_callback: lock granted after lock request "
" dangling lock!\n"); "failed; dangling lock!\n");
goto out; goto out;
} }
@ -186,25 +200,31 @@ out:
return rv; return rv;
} }
int gdlm_punlock(void *lockspace, struct lm_lockname *name, int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file *file, struct file_lock *fl) struct file_lock *fl)
{ {
struct gdlm_ls *ls = lockspace; struct dlm_ls *ls;
struct plock_op *op; struct plock_op *op;
int rv; int rv;
ls = dlm_find_lockspace_local(lockspace);
if (!ls)
return -EINVAL;
op = kzalloc(sizeof(*op), GFP_KERNEL); op = kzalloc(sizeof(*op), GFP_KERNEL);
if (!op) if (!op) {
return -ENOMEM; rv = -ENOMEM;
goto out;
}
if (posix_lock_file_wait(file, fl) < 0) if (posix_lock_file_wait(file, fl) < 0)
log_error("gdlm_punlock: vfs unlock error %x,%llx", log_error(ls, "dlm_posix_unlock: vfs unlock error %llx",
name->ln_type, (unsigned long long)name->ln_number); (unsigned long long)number);
op->info.optype = GDLM_PLOCK_OP_UNLOCK; op->info.optype = DLM_PLOCK_OP_UNLOCK;
op->info.pid = fl->fl_pid; op->info.pid = fl->fl_pid;
op->info.fsid = ls->id; op->info.fsid = ls->ls_global_id;
op->info.number = name->ln_number; op->info.number = number;
op->info.start = fl->fl_start; op->info.start = fl->fl_start;
op->info.end = fl->fl_end; op->info.end = fl->fl_end;
if (fl->fl_lmops && fl->fl_lmops->fl_grant) if (fl->fl_lmops && fl->fl_lmops->fl_grant)
@ -217,7 +237,8 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
spin_lock(&ops_lock); spin_lock(&ops_lock);
if (!list_empty(&op->list)) { if (!list_empty(&op->list)) {
printk(KERN_INFO "punlock op on list\n"); log_error(ls, "dlm_posix_unlock: op on list %llx",
(unsigned long long)number);
list_del(&op->list); list_del(&op->list);
} }
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
@ -228,25 +249,34 @@ int gdlm_punlock(void *lockspace, struct lm_lockname *name,
rv = 0; rv = 0;
kfree(op); kfree(op);
out:
dlm_put_lockspace(ls);
return rv; return rv;
} }
EXPORT_SYMBOL_GPL(dlm_posix_unlock);
int gdlm_plock_get(void *lockspace, struct lm_lockname *name, int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file *file, struct file_lock *fl) struct file_lock *fl)
{ {
struct gdlm_ls *ls = lockspace; struct dlm_ls *ls;
struct plock_op *op; struct plock_op *op;
int rv; int rv;
op = kzalloc(sizeof(*op), GFP_KERNEL); ls = dlm_find_lockspace_local(lockspace);
if (!op) if (!ls)
return -ENOMEM; return -EINVAL;
op->info.optype = GDLM_PLOCK_OP_GET; op = kzalloc(sizeof(*op), GFP_KERNEL);
if (!op) {
rv = -ENOMEM;
goto out;
}
op->info.optype = DLM_PLOCK_OP_GET;
op->info.pid = fl->fl_pid; op->info.pid = fl->fl_pid;
op->info.ex = (fl->fl_type == F_WRLCK); op->info.ex = (fl->fl_type == F_WRLCK);
op->info.fsid = ls->id; op->info.fsid = ls->ls_global_id;
op->info.number = name->ln_number; op->info.number = number;
op->info.start = fl->fl_start; op->info.start = fl->fl_start;
op->info.end = fl->fl_end; op->info.end = fl->fl_end;
if (fl->fl_lmops && fl->fl_lmops->fl_grant) if (fl->fl_lmops && fl->fl_lmops->fl_grant)
@ -259,7 +289,8 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
spin_lock(&ops_lock); spin_lock(&ops_lock);
if (!list_empty(&op->list)) { if (!list_empty(&op->list)) {
printk(KERN_INFO "plock_get op on list\n"); log_error(ls, "dlm_posix_get: op on list %llx",
(unsigned long long)number);
list_del(&op->list); list_del(&op->list);
} }
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
@ -281,14 +312,17 @@ int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
} }
kfree(op); kfree(op);
out:
dlm_put_lockspace(ls);
return rv; return rv;
} }
EXPORT_SYMBOL_GPL(dlm_posix_get);
/* a read copies out one plock request from the send list */ /* a read copies out one plock request from the send list */
static ssize_t dev_read(struct file *file, char __user *u, size_t count, static ssize_t dev_read(struct file *file, char __user *u, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
struct gdlm_plock_info info; struct dlm_plock_info info;
struct plock_op *op = NULL; struct plock_op *op = NULL;
if (count < sizeof(info)) if (count < sizeof(info))
@ -315,7 +349,7 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
static ssize_t dev_write(struct file *file, const char __user *u, size_t count, static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
loff_t *ppos) loff_t *ppos)
{ {
struct gdlm_plock_info info; struct dlm_plock_info info;
struct plock_op *op; struct plock_op *op;
int found = 0; int found = 0;
@ -345,12 +379,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
struct plock_xop *xop; struct plock_xop *xop;
xop = (struct plock_xop *)op; xop = (struct plock_xop *)op;
if (xop->callback) if (xop->callback)
count = gdlm_plock_callback(op); count = dlm_plock_callback(op);
else else
wake_up(&recv_wq); wake_up(&recv_wq);
} else } else
printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid, log_print("dev_write no op %x %llx", info.fsid,
(unsigned long long)info.number); (unsigned long long)info.number);
return count; return count;
} }
@ -377,11 +411,11 @@ static const struct file_operations dev_fops = {
static struct miscdevice plock_dev_misc = { static struct miscdevice plock_dev_misc = {
.minor = MISC_DYNAMIC_MINOR, .minor = MISC_DYNAMIC_MINOR,
.name = GDLM_PLOCK_MISC_NAME, .name = DLM_PLOCK_MISC_NAME,
.fops = &dev_fops .fops = &dev_fops
}; };
int gdlm_plock_init(void) int dlm_plock_init(void)
{ {
int rv; int rv;
@ -393,14 +427,13 @@ int gdlm_plock_init(void)
rv = misc_register(&plock_dev_misc); rv = misc_register(&plock_dev_misc);
if (rv) if (rv)
printk(KERN_INFO "gdlm_plock_init: misc_register failed %d", log_print("dlm_plock_init: misc_register failed %d", rv);
rv);
return rv; return rv;
} }
void gdlm_plock_exit(void) void dlm_plock_exit(void)
{ {
if (misc_deregister(&plock_dev_misc) < 0) if (misc_deregister(&plock_dev_misc) < 0)
printk(KERN_INFO "gdlm_plock_exit: misc_deregister failed"); log_print("dlm_plock_exit: misc_deregister failed");
} }

View File

@ -257,6 +257,7 @@ static void do_ls_recovery(struct dlm_ls *ls)
if (rv) { if (rv) {
ls_recover(ls, rv); ls_recover(ls, rv);
kfree(rv->nodeids); kfree(rv->nodeids);
kfree(rv->new);
kfree(rv); kfree(rv);
} }
} }

View File

@ -1,3 +1,3 @@
obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o obj-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o
lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o plock.o lock_dlm-y := lock.o main.o mount.o sysfs.o thread.o

View File

@ -25,6 +25,7 @@
#include <net/sock.h> #include <net/sock.h>
#include <linux/dlm.h> #include <linux/dlm.h>
#include <linux/dlm_plock.h>
#include <linux/lm_interface.h> #include <linux/lm_interface.h>
/* /*
@ -173,17 +174,6 @@ void gdlm_cancel(void *);
int gdlm_hold_lvb(void *, char **); int gdlm_hold_lvb(void *, char **);
void gdlm_unhold_lvb(void *, char *); void gdlm_unhold_lvb(void *, char *);
/* plock.c */
int gdlm_plock_init(void);
void gdlm_plock_exit(void);
int gdlm_plock(void *, struct lm_lockname *, struct file *, int,
struct file_lock *);
int gdlm_plock_get(void *, struct lm_lockname *, struct file *,
struct file_lock *);
int gdlm_punlock(void *, struct lm_lockname *, struct file *,
struct file_lock *);
/* mount.c */ /* mount.c */
extern const struct lm_lockops gdlm_ops; extern const struct lm_lockops gdlm_ops;

View File

@ -28,13 +28,6 @@ static int __init init_lock_dlm(void)
return error; return error;
} }
error = gdlm_plock_init();
if (error) {
gdlm_sysfs_exit();
gfs2_unregister_lockproto(&gdlm_ops);
return error;
}
printk(KERN_INFO printk(KERN_INFO
"Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__); "Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__);
return 0; return 0;
@ -42,7 +35,6 @@ static int __init init_lock_dlm(void)
static void __exit exit_lock_dlm(void) static void __exit exit_lock_dlm(void)
{ {
gdlm_plock_exit();
gdlm_sysfs_exit(); gdlm_sysfs_exit();
gfs2_unregister_lockproto(&gdlm_ops); gfs2_unregister_lockproto(&gdlm_ops);
} }

View File

@ -236,6 +236,27 @@ static void gdlm_withdraw(void *lockspace)
gdlm_kobject_release(ls); gdlm_kobject_release(ls);
} }
static int gdlm_plock(void *lockspace, struct lm_lockname *name,
struct file *file, int cmd, struct file_lock *fl)
{
struct gdlm_ls *ls = lockspace;
return dlm_posix_lock(ls->dlm_lockspace, name->ln_number, file, cmd, fl);
}
static int gdlm_punlock(void *lockspace, struct lm_lockname *name,
struct file *file, struct file_lock *fl)
{
struct gdlm_ls *ls = lockspace;
return dlm_posix_unlock(ls->dlm_lockspace, name->ln_number, file, fl);
}
static int gdlm_plock_get(void *lockspace, struct lm_lockname *name,
struct file *file, struct file_lock *fl)
{
struct gdlm_ls *ls = lockspace;
return dlm_posix_get(ls->dlm_lockspace, name->ln_number, file, fl);
}
const struct lm_lockops gdlm_ops = { const struct lm_lockops gdlm_ops = {
.lm_proto_name = "lock_dlm", .lm_proto_name = "lock_dlm",
.lm_mount = gdlm_mount, .lm_mount = gdlm_mount,

View File

@ -100,7 +100,7 @@ header-y += ixjuser.h
header-y += jffs2.h header-y += jffs2.h
header-y += keyctl.h header-y += keyctl.h
header-y += limits.h header-y += limits.h
header-y += lock_dlm_plock.h header-y += dlm_plock.h
header-y += magic.h header-y += magic.h
header-y += major.h header-y += major.h
header-y += matroxfb.h header-y += matroxfb.h

View File

@ -21,10 +21,7 @@
/* Lock levels and flags are here */ /* Lock levels and flags are here */
#include <linux/dlmconstants.h> #include <linux/dlmconstants.h>
#include <linux/types.h>
#define DLM_RESNAME_MAXLEN 64
typedef void dlm_lockspace_t; typedef void dlm_lockspace_t;
@ -63,7 +60,7 @@ typedef void dlm_lockspace_t;
struct dlm_lksb { struct dlm_lksb {
int sb_status; int sb_status;
uint32_t sb_lkid; __u32 sb_lkid;
char sb_flags; char sb_flags;
char * sb_lvbptr; char * sb_lvbptr;
}; };

View File

@ -11,10 +11,16 @@
******************************************************************************* *******************************************************************************
******************************************************************************/ ******************************************************************************/
#ifndef _LINUX_DLM_DEVICE_H
#define _LINUX_DLM_DEVICE_H
/* This is the device interface for dlm, most users will use a library /* This is the device interface for dlm, most users will use a library
* interface. * interface.
*/ */
#include <linux/dlm.h>
#include <linux/types.h>
#define DLM_USER_LVB_LEN 32 #define DLM_USER_LVB_LEN 32
/* Version of the device interface */ /* Version of the device interface */
@ -94,10 +100,9 @@ struct dlm_lock_result {
#define DLM_USER_PURGE 6 #define DLM_USER_PURGE 6
#define DLM_USER_DEADLOCK 7 #define DLM_USER_DEADLOCK 7
/* Arbitrary length restriction */
#define MAX_LS_NAME_LEN 64
/* Lockspace flags */ /* Lockspace flags */
#define DLM_USER_LSFLG_AUTOFREE 1 #define DLM_USER_LSFLG_AUTOFREE 1
#define DLM_USER_LSFLG_FORCEFREE 2 #define DLM_USER_LSFLG_FORCEFREE 2
#endif

50
include/linux/dlm_plock.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2005-2008 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 __DLM_PLOCK_DOT_H__
#define __DLM_PLOCK_DOT_H__
#define DLM_PLOCK_MISC_NAME "dlm_plock"
#define DLM_PLOCK_VERSION_MAJOR 1
#define DLM_PLOCK_VERSION_MINOR 1
#define DLM_PLOCK_VERSION_PATCH 0
enum {
DLM_PLOCK_OP_LOCK = 1,
DLM_PLOCK_OP_UNLOCK,
DLM_PLOCK_OP_GET,
};
struct dlm_plock_info {
__u32 version[3];
__u8 optype;
__u8 ex;
__u8 wait;
__u8 pad;
__u32 pid;
__s32 nodeid;
__s32 rv;
__u32 fsid;
__u64 number;
__u64 start;
__u64 end;
__u64 owner;
};
#ifdef __KERNEL__
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
int cmd, struct file_lock *fl);
int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl);
int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl);
#endif /* __KERNEL__ */
#endif

View File

@ -18,6 +18,10 @@
* Constants used by DLM interface. * Constants used by DLM interface.
*/ */
#define DLM_LOCKSPACE_LEN 64
#define DLM_RESNAME_MAXLEN 64
/* /*
* Lock Modes * Lock Modes
*/ */

View File

@ -1,41 +0,0 @@
/*
* Copyright (C) 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_PLOCK_DOT_H__
#define __LOCK_DLM_PLOCK_DOT_H__
#define GDLM_PLOCK_MISC_NAME "lock_dlm_plock"
#define GDLM_PLOCK_VERSION_MAJOR 1
#define GDLM_PLOCK_VERSION_MINOR 1
#define GDLM_PLOCK_VERSION_PATCH 0
enum {
GDLM_PLOCK_OP_LOCK = 1,
GDLM_PLOCK_OP_UNLOCK,
GDLM_PLOCK_OP_GET,
};
struct gdlm_plock_info {
__u32 version[3];
__u8 optype;
__u8 ex;
__u8 wait;
__u8 pad;
__u32 pid;
__s32 nodeid;
__s32 rv;
__u32 fsid;
__u64 number;
__u64 start;
__u64 end;
__u64 owner;
};
#endif