From e7fd41792fc0ee52a05fcaac87511f118328d147 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 18 Jan 2006 09:30:29 +0000 Subject: [DLM] The core of the DLM for GFS2/CLVM This is the core of the distributed lock manager which is required to use GFS2 as a cluster filesystem. It is also used by CLVM and can be used as a standalone lock manager independantly of either of these two projects. It implements VAX-style locking modes. Signed-off-by: David Teigland Signed-off-by: Steve Whitehouse --- fs/dlm/member.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 fs/dlm/member.c (limited to 'fs/dlm/member.c') diff --git a/fs/dlm/member.c b/fs/dlm/member.c new file mode 100644 index 00000000000000..439249b62a574a --- /dev/null +++ b/fs/dlm/member.c @@ -0,0 +1,314 @@ +/****************************************************************************** +******************************************************************************* +** +** 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. +** +******************************************************************************* +******************************************************************************/ + +#include "dlm_internal.h" +#include "lockspace.h" +#include "member.h" +#include "recoverd.h" +#include "recover.h" +#include "lowcomms.h" +#include "rcom.h" +#include "config.h" + +/* + * Following called by dlm_recoverd thread + */ + +static void add_ordered_member(struct dlm_ls *ls, struct dlm_member *new) +{ + struct dlm_member *memb = NULL; + struct list_head *tmp; + struct list_head *newlist = &new->list; + struct list_head *head = &ls->ls_nodes; + + list_for_each(tmp, head) { + memb = list_entry(tmp, struct dlm_member, list); + if (new->nodeid < memb->nodeid) + break; + } + + if (!memb) + list_add_tail(newlist, head); + else { + /* FIXME: can use list macro here */ + newlist->prev = tmp->prev; + newlist->next = tmp; + tmp->prev->next = newlist; + tmp->prev = newlist; + } +} + +static int dlm_add_member(struct dlm_ls *ls, int nodeid) +{ + struct dlm_member *memb; + int w; + + memb = kmalloc(sizeof(struct dlm_member), GFP_KERNEL); + if (!memb) + return -ENOMEM; + + w = dlm_node_weight(ls->ls_name, nodeid); + if (w < 0) + return w; + + memb->nodeid = nodeid; + memb->weight = w; + add_ordered_member(ls, memb); + ls->ls_num_nodes++; + return 0; +} + +static void dlm_remove_member(struct dlm_ls *ls, struct dlm_member *memb) +{ + list_move(&memb->list, &ls->ls_nodes_gone); + ls->ls_num_nodes--; +} + +static int dlm_is_member(struct dlm_ls *ls, int nodeid) +{ + struct dlm_member *memb; + + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (memb->nodeid == nodeid) + return TRUE; + } + return FALSE; +} + +int dlm_is_removed(struct dlm_ls *ls, int nodeid) +{ + struct dlm_member *memb; + + list_for_each_entry(memb, &ls->ls_nodes_gone, list) { + if (memb->nodeid == nodeid) + return TRUE; + } + return FALSE; +} + +static void clear_memb_list(struct list_head *head) +{ + struct dlm_member *memb; + + while (!list_empty(head)) { + memb = list_entry(head->next, struct dlm_member, list); + list_del(&memb->list); + kfree(memb); + } +} + +void dlm_clear_members(struct dlm_ls *ls) +{ + clear_memb_list(&ls->ls_nodes); + ls->ls_num_nodes = 0; +} + +void dlm_clear_members_gone(struct dlm_ls *ls) +{ + clear_memb_list(&ls->ls_nodes_gone); +} + +static void make_member_array(struct dlm_ls *ls) +{ + struct dlm_member *memb; + int i, w, x = 0, total = 0, all_zero = 0, *array; + + kfree(ls->ls_node_array); + ls->ls_node_array = NULL; + + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (memb->weight) + total += memb->weight; + } + + /* all nodes revert to weight of 1 if all have weight 0 */ + + if (!total) { + total = ls->ls_num_nodes; + all_zero = 1; + } + + ls->ls_total_weight = total; + + array = kmalloc(sizeof(int) * total, GFP_KERNEL); + if (!array) + return; + + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (!all_zero && !memb->weight) + continue; + + if (all_zero) + w = 1; + else + w = memb->weight; + + DLM_ASSERT(x < total, printk("total %d x %d\n", total, x);); + + for (i = 0; i < w; i++) + array[x++] = memb->nodeid; + } + + ls->ls_node_array = array; +} + +/* send a status request to all members just to establish comms connections */ + +static void ping_members(struct dlm_ls *ls) +{ + struct dlm_member *memb; + list_for_each_entry(memb, &ls->ls_nodes, list) + dlm_rcom_status(ls, memb->nodeid); +} + +int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) +{ + struct dlm_member *memb, *safe; + int i, error, found, pos = 0, neg = 0, low = -1; + + /* move departed members from ls_nodes to ls_nodes_gone */ + + list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { + found = FALSE; + for (i = 0; i < rv->node_count; i++) { + if (memb->nodeid == rv->nodeids[i]) { + found = TRUE; + break; + } + } + + if (!found) { + neg++; + dlm_remove_member(ls, memb); + log_debug(ls, "remove member %d", memb->nodeid); + } + } + + /* add new members to ls_nodes */ + + for (i = 0; i < rv->node_count; i++) { + if (dlm_is_member(ls, rv->nodeids[i])) + continue; + dlm_add_member(ls, rv->nodeids[i]); + pos++; + log_debug(ls, "add member %d", rv->nodeids[i]); + } + + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (low == -1 || memb->nodeid < low) + low = memb->nodeid; + } + ls->ls_low_nodeid = low; + + make_member_array(ls); + dlm_set_recover_status(ls, DLM_RS_NODES); + *neg_out = neg; + + ping_members(ls); + + error = dlm_recover_members_wait(ls); + log_debug(ls, "total members %d", ls->ls_num_nodes); + return error; +} + +/* + * Following called from lockspace.c + */ + +int dlm_ls_stop(struct dlm_ls *ls) +{ + int new; + + /* + * A stop cancels any recovery that's in progress (see RECOVERY_STOP, + * dlm_recovery_stopped()) and prevents any new locks from being + * processed (see RUNNING, dlm_locking_stopped()). + */ + + spin_lock(&ls->ls_recover_lock); + set_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); + new = test_and_clear_bit(LSFL_RUNNING, &ls->ls_flags); + ls->ls_recover_seq++; + spin_unlock(&ls->ls_recover_lock); + + /* + * This in_recovery lock does two things: + * + * 1) Keeps this function from returning until all threads are out + * of locking routines and locking is truely stopped. + * 2) Keeps any new requests from being processed until it's unlocked + * when recovery is complete. + */ + + if (new) + down_write(&ls->ls_in_recovery); + + /* + * The recoverd suspend/resume makes sure that dlm_recoverd (if + * running) has noticed the clearing of RUNNING above and quit + * processing the previous recovery. This will be true for all nodes + * before any nodes start the new recovery. + */ + + dlm_recoverd_suspend(ls); + ls->ls_recover_status = 0; + dlm_recoverd_resume(ls); + return 0; +} + +int dlm_ls_start(struct dlm_ls *ls) +{ + struct dlm_recover *rv = NULL, *rv_old; + int *ids = NULL; + int error, count; + + rv = kmalloc(sizeof(struct dlm_recover), GFP_KERNEL); + if (!rv) + return -ENOMEM; + memset(rv, 0, sizeof(struct dlm_recover)); + + error = count = dlm_nodeid_list(ls->ls_name, &ids); + if (error <= 0) + goto fail; + + spin_lock(&ls->ls_recover_lock); + + /* the lockspace needs to be stopped before it can be started */ + + if (!dlm_locking_stopped(ls)) { + spin_unlock(&ls->ls_recover_lock); + log_error(ls, "start ignored: lockspace running"); + error = -EINVAL; + goto fail; + } + + rv->nodeids = ids; + rv->node_count = count; + rv->seq = ++ls->ls_recover_seq; + rv_old = ls->ls_recover_args; + ls->ls_recover_args = rv; + spin_unlock(&ls->ls_recover_lock); + + if (rv_old) { + kfree(rv_old->nodeids); + kfree(rv_old); + } + + dlm_recoverd_kick(ls); + return 0; + + fail: + kfree(rv); + kfree(ids); + return error; +} + -- cgit 1.2.3-korg From 901359256b2666f52a3a7d3f31927677e91b3a2a Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 20 Jan 2006 08:47:07 +0000 Subject: [DLM] Update DLM to the latest patch level Signed-off-by: David Teigland Signed-off-by: Steve Whitehouse --- fs/dlm/ast.c | 16 ++++++------ fs/dlm/config.c | 20 +++++++------- fs/dlm/debug_fs.c | 4 +-- fs/dlm/device.c | 55 +++++++++++++++++++++++---------------- fs/dlm/dir.c | 4 +-- fs/dlm/dlm_internal.h | 23 ++++------------ fs/dlm/lock.c | 72 +++++++++++++++++++++++++-------------------------- fs/dlm/lock.h | 4 +-- fs/dlm/lockspace.c | 21 +++++++-------- fs/dlm/member.c | 17 ++++++------ fs/dlm/midcomms.c | 2 +- fs/dlm/recover.c | 18 ++++++------- fs/dlm/recoverd.c | 16 ++++++------ fs/dlm/requestqueue.c | 26 +++++++++---------- 14 files changed, 147 insertions(+), 151 deletions(-) (limited to 'fs/dlm/member.c') diff --git a/fs/dlm/ast.c b/fs/dlm/ast.c index 2bd1c5e1a72c73..57bdf09b520a8a 100644 --- a/fs/dlm/ast.c +++ b/fs/dlm/ast.c @@ -21,7 +21,7 @@ static struct list_head ast_queue; static spinlock_t ast_queue_lock; static struct task_struct * astd_task; static unsigned long astd_wakeflags; -static struct semaphore astd_running; +static struct mutex astd_running; void dlm_del_ast(struct dlm_lkb *lkb) @@ -56,7 +56,7 @@ static void process_asts(void) int type = 0, found, bmode; for (;;) { - found = FALSE; + found = 0; spin_lock(&ast_queue_lock); list_for_each_entry(lkb, &ast_queue, lkb_astqueue) { r = lkb->lkb_resource; @@ -68,7 +68,7 @@ static void process_asts(void) list_del(&lkb->lkb_astqueue); type = lkb->lkb_ast_type; lkb->lkb_ast_type = 0; - found = TRUE; + found = 1; break; } spin_unlock(&ast_queue_lock); @@ -117,10 +117,10 @@ static int dlm_astd(void *data) schedule(); set_current_state(TASK_RUNNING); - down(&astd_running); + mutex_lock(&astd_running); if (test_and_clear_bit(WAKE_ASTS, &astd_wakeflags)) process_asts(); - up(&astd_running); + mutex_unlock(&astd_running); } return 0; } @@ -140,7 +140,7 @@ int dlm_astd_start(void) INIT_LIST_HEAD(&ast_queue); spin_lock_init(&ast_queue_lock); - init_MUTEX(&astd_running); + mutex_init(&astd_running); p = kthread_run(dlm_astd, NULL, "dlm_astd"); if (IS_ERR(p)) @@ -157,11 +157,11 @@ void dlm_astd_stop(void) void dlm_astd_suspend(void) { - down(&astd_running); + mutex_lock(&astd_running); } void dlm_astd_resume(void) { - up(&astd_running); + mutex_unlock(&astd_running); } diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 024ace9973a81b..87df9616415e5d 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -162,7 +162,7 @@ struct spaces { struct space { struct config_group group; struct list_head members; - struct semaphore members_lock; + struct mutex members_lock; int members_count; }; @@ -374,7 +374,7 @@ static struct config_group *make_space(struct config_group *g, const char *name) sp->group.default_groups[1] = NULL; INIT_LIST_HEAD(&sp->members); - init_MUTEX(&sp->members_lock); + mutex_init(&sp->members_lock); sp->members_count = 0; return &sp->group; @@ -453,10 +453,10 @@ static struct config_item *make_node(struct config_group *g, const char *name) nd->nodeid = -1; nd->weight = 1; /* default weight of 1 if none is set */ - down(&sp->members_lock); + mutex_lock(&sp->members_lock); list_add(&nd->list, &sp->members); sp->members_count++; - up(&sp->members_lock); + mutex_unlock(&sp->members_lock); return &nd->item; } @@ -466,10 +466,10 @@ static void drop_node(struct config_group *g, struct config_item *i) struct space *sp = to_space(g->cg_item.ci_parent); struct node *nd = to_node(i); - down(&sp->members_lock); + mutex_lock(&sp->members_lock); list_del(&nd->list); sp->members_count--; - up(&sp->members_lock); + mutex_unlock(&sp->members_lock); config_item_put(i); } @@ -677,7 +677,7 @@ int dlm_nodeid_list(char *lsname, int **ids_out) if (!sp) return -EEXIST; - down(&sp->members_lock); + mutex_lock(&sp->members_lock); if (!sp->members_count) { rv = 0; goto out; @@ -698,7 +698,7 @@ int dlm_nodeid_list(char *lsname, int **ids_out) *ids_out = ids; out: - up(&sp->members_lock); + mutex_unlock(&sp->members_lock); put_space(sp); return rv; } @@ -713,14 +713,14 @@ int dlm_node_weight(char *lsname, int nodeid) if (!sp) goto out; - down(&sp->members_lock); + mutex_lock(&sp->members_lock); list_for_each_entry(nd, &sp->members, list) { if (nd->nodeid != nodeid) continue; w = nd->weight; break; } - up(&sp->members_lock); + mutex_unlock(&sp->members_lock); put_space(sp); out: return w; diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c index 98b49a1ece4713..5080bbffd586a7 100644 --- a/fs/dlm/debug_fs.c +++ b/fs/dlm/debug_fs.c @@ -63,12 +63,12 @@ static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, /* FIXME: this warns on Alpha */ if (lkb->lkb_status == DLM_LKSTS_CONVERT || lkb->lkb_status == DLM_LKSTS_GRANTED) - seq_printf(s, " %" PRIx64 "-%" PRIx64, + seq_printf(s, " %llx-%llx", lkb->lkb_range[GR_RANGE_START], lkb->lkb_range[GR_RANGE_END]); if (lkb->lkb_status == DLM_LKSTS_CONVERT || lkb->lkb_status == DLM_LKSTS_WAITING) - seq_printf(s, " (%" PRIx64 "-%" PRIx64 ")", + seq_printf(s, " (%llx-%llx)", lkb->lkb_range[RQ_RANGE_START], lkb->lkb_range[RQ_RANGE_END]); } diff --git a/fs/dlm/device.c b/fs/dlm/device.c index a8bf600ed13dd7..899d4f92a4d714 100644 --- a/fs/dlm/device.c +++ b/fs/dlm/device.c @@ -43,7 +43,7 @@ static struct file_operations _dlm_fops; static const char *name_prefix="dlm"; static struct list_head user_ls_list; -static struct semaphore user_ls_lock; +static struct mutex user_ls_lock; /* Lock infos are stored in here indexed by lock ID */ static DEFINE_IDR(lockinfo_idr); @@ -53,6 +53,7 @@ static rwlock_t lockinfo_lock; #define LI_FLAG_COMPLETE 1 #define LI_FLAG_FIRSTLOCK 2 #define LI_FLAG_PERSISTENT 3 +#define LI_FLAG_ONLIST 4 /* flags in ls_flags*/ #define LS_FLAG_DELETED 1 @@ -211,18 +212,18 @@ static struct user_ls *find_lockspace(int minor) { struct user_ls *lsinfo; - down(&user_ls_lock); + mutex_lock(&user_ls_lock); lsinfo = __find_lockspace(minor); - up(&user_ls_lock); + mutex_unlock(&user_ls_lock); return lsinfo; } static void add_lockspace_to_list(struct user_ls *lsinfo) { - down(&user_ls_lock); + mutex_lock(&user_ls_lock); list_add(&lsinfo->ls_list, &user_ls_list); - up(&user_ls_lock); + mutex_unlock(&user_ls_lock); } /* Register a lockspace with the DLM and create a misc @@ -235,12 +236,11 @@ static int register_lockspace(char *name, struct user_ls **ls, int flags) namelen = strlen(name)+strlen(name_prefix)+2; - newls = kmalloc(sizeof(struct user_ls), GFP_KERNEL); + newls = kzalloc(sizeof(struct user_ls), GFP_KERNEL); if (!newls) return -ENOMEM; - memset(newls, 0, sizeof(struct user_ls)); - newls->ls_miscinfo.name = kmalloc(namelen, GFP_KERNEL); + newls->ls_miscinfo.name = kzalloc(namelen, GFP_KERNEL); if (!newls->ls_miscinfo.name) { kfree(newls); return -ENOMEM; @@ -277,7 +277,7 @@ static int register_lockspace(char *name, struct user_ls **ls, int flags) return 0; } -/* Called with the user_ls_lock semaphore held */ +/* Called with the user_ls_lock mutex held */ static int unregister_lockspace(struct user_ls *lsinfo, int force) { int status; @@ -305,11 +305,10 @@ static int unregister_lockspace(struct user_ls *lsinfo, int force) static void add_to_astqueue(struct lock_info *li, void *astaddr, void *astparam, int lvb_updated) { - struct ast_info *ast = kmalloc(sizeof(struct ast_info), GFP_KERNEL); + struct ast_info *ast = kzalloc(sizeof(struct ast_info), GFP_KERNEL); if (!ast) return; - memset(ast, 0, sizeof(*ast)); ast->result.user_astparam = astparam; ast->result.user_astaddr = astaddr; ast->result.user_lksb = li->li_user_lksb; @@ -382,6 +381,7 @@ static void ast_routine(void *param) spin_lock(&li->li_file->fi_li_lock); list_del(&li->li_ownerqueue); + clear_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&li->li_file->fi_li_lock); release_lockinfo(li); return; @@ -437,7 +437,7 @@ static int dlm_open(struct inode *inode, struct file *file) if (!lsinfo) return -ENOENT; - f = kmalloc(sizeof(struct file_info), GFP_KERNEL); + f = kzalloc(sizeof(struct file_info), GFP_KERNEL); if (!f) return -ENOMEM; @@ -570,7 +570,7 @@ static int dlm_close(struct inode *inode, struct file *file) * then free the struct. If it's an AUTOFREE lockspace * then free the whole thing. */ - down(&user_ls_lock); + mutex_lock(&user_ls_lock); if (atomic_dec_and_test(&lsinfo->ls_refcnt)) { if (lsinfo->ls_lockspace) { @@ -582,7 +582,7 @@ static int dlm_close(struct inode *inode, struct file *file) kfree(lsinfo); } } - up(&user_ls_lock); + mutex_unlock(&user_ls_lock); put_file_info(f); /* Restore signals */ @@ -620,10 +620,10 @@ static int do_user_remove_lockspace(struct file_info *fi, uint8_t cmd, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - down(&user_ls_lock); + mutex_lock(&user_ls_lock); lsinfo = __find_lockspace(kparams->minor); if (!lsinfo) { - up(&user_ls_lock); + mutex_unlock(&user_ls_lock); return -EINVAL; } @@ -631,7 +631,7 @@ static int do_user_remove_lockspace(struct file_info *fi, uint8_t cmd, force = 2; status = unregister_lockspace(lsinfo, force); - up(&user_ls_lock); + mutex_unlock(&user_ls_lock); return status; } @@ -752,7 +752,7 @@ static struct lock_info *allocate_lockinfo(struct file_info *fi, uint8_t cmd, if (!try_module_get(THIS_MODULE)) return NULL; - li = kmalloc(sizeof(struct lock_info), GFP_KERNEL); + li = kzalloc(sizeof(struct lock_info), GFP_KERNEL); if (li) { li->li_magic = LOCKINFO_MAGIC; li->li_file = fi; @@ -800,8 +800,10 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, /* If this is a persistent lock we will have to create a lockinfo again */ - if (!li && DLM_LKF_PERSISTENT) { + if (!li && (kparams->flags & DLM_LKF_PERSISTENT)) { li = allocate_lockinfo(fi, cmd, kparams); + if (!li) + return -ENOMEM; li->li_lksb.sb_lkid = kparams->lkid; li->li_castaddr = kparams->castaddr; @@ -887,6 +889,7 @@ static int do_user_lock(struct file_info *fi, uint8_t cmd, spin_lock(&fi->fi_li_lock); list_add(&li->li_ownerqueue, &fi->fi_li_list); + set_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&fi->fi_li_lock); if (add_lockinfo(li)) printk(KERN_WARNING "Add lockinfo failed\n"); @@ -914,12 +917,13 @@ static int do_user_unlock(struct file_info *fi, uint8_t cmd, li = get_lockinfo(kparams->lkid); if (!li) { li = allocate_lockinfo(fi, cmd, kparams); + if (!li) + return -ENOMEM; spin_lock(&fi->fi_li_lock); list_add(&li->li_ownerqueue, &fi->fi_li_list); + set_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&fi->fi_li_lock); } - if (!li) - return -ENOMEM; if (li->li_magic != LOCKINFO_MAGIC) return -EINVAL; @@ -932,6 +936,12 @@ static int do_user_unlock(struct file_info *fi, uint8_t cmd, if (kparams->flags & DLM_LKF_CANCEL && li->li_grmode != -1) convert_cancel = 1; + /* Wait until dlm_lock() has completed */ + if (!test_bit(LI_FLAG_ONLIST, &li->li_flags)) { + down(&li->li_firstlock); + up(&li->li_firstlock); + } + /* dlm_unlock() passes a 0 for castaddr which means don't overwrite the existing li_castaddr as that's the completion routine for unlocks. dlm_unlock_wait() specifies a new AST routine to be @@ -947,6 +957,7 @@ static int do_user_unlock(struct file_info *fi, uint8_t cmd, if (!status && !convert_cancel) { spin_lock(&fi->fi_li_lock); list_del(&li->li_ownerqueue); + clear_bit(LI_FLAG_ONLIST, &li->li_flags); spin_unlock(&fi->fi_li_lock); } @@ -1055,7 +1066,7 @@ static int __init dlm_device_init(void) int r; INIT_LIST_HEAD(&user_ls_list); - init_MUTEX(&user_ls_lock); + mutex_init(&user_ls_lock); rwlock_init(&lockinfo_lock); ctl_device.name = "dlm-control"; diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c index 0f1dde54bcd279..46754553fdcc4a 100644 --- a/fs/dlm/dir.c +++ b/fs/dlm/dir.c @@ -33,7 +33,7 @@ static void put_free_de(struct dlm_ls *ls, struct dlm_direntry *de) static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len) { - int found = FALSE; + int found = 0; struct dlm_direntry *de; spin_lock(&ls->ls_recover_list_lock); @@ -42,7 +42,7 @@ static struct dlm_direntry *get_free_de(struct dlm_ls *ls, int len) list_del(&de->list); de->master_nodeid = 0; memset(de->name, 0, len); - found = TRUE; + found = 1; break; } } diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 0020cd07baf708..16f20cfd9197c9 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -42,20 +43,6 @@ #define DLM_LOCKSPACE_LEN 64 -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#if (BITS_PER_LONG == 64) -#define PRIx64 "lx" -#else -#define PRIx64 "Lx" -#endif - /* Size of the temp buffer midcomms allocates on the stack. We try to make this large enough so most messages fit. FIXME: should sctp make this unnecessary? */ @@ -266,7 +253,7 @@ struct dlm_lkb { struct dlm_rsb { struct dlm_ls *res_ls; /* the lockspace */ struct kref res_ref; - struct semaphore res_sem; + struct mutex res_mutex; unsigned long res_flags; int res_length; /* length of rsb name */ int res_nodeid; @@ -449,7 +436,7 @@ struct dlm_ls { struct dlm_dirtable *ls_dirtbl; uint32_t ls_dirtbl_size; - struct semaphore ls_waiters_sem; + struct mutex ls_waiters_mutex; struct list_head ls_waiters; /* lkbs needing a reply */ struct list_head ls_nodes; /* current nodes in ls */ @@ -472,14 +459,14 @@ struct dlm_ls { struct timer_list ls_timer; struct task_struct *ls_recoverd_task; - struct semaphore ls_recoverd_active; + struct mutex ls_recoverd_active; spinlock_t ls_recover_lock; uint32_t ls_recover_status; /* DLM_RS_ */ uint64_t ls_recover_seq; struct dlm_recover *ls_recover_args; struct rw_semaphore ls_in_recovery; /* block local requests */ struct list_head ls_requestqueue;/* queue remote requests */ - struct semaphore ls_requestqueue_lock; + struct mutex ls_requestqueue_mutex; char *ls_recover_buf; struct list_head ls_recover_list; spinlock_t ls_recover_list_lock; diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 81efb361f95df9..29d3b95dbb6369 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -215,15 +215,15 @@ static inline int is_master_copy(struct dlm_lkb *lkb) { if (lkb->lkb_flags & DLM_IFL_MSTCPY) DLM_ASSERT(lkb->lkb_nodeid, dlm_print_lkb(lkb);); - return (lkb->lkb_flags & DLM_IFL_MSTCPY) ? TRUE : FALSE; + return (lkb->lkb_flags & DLM_IFL_MSTCPY) ? 1 : 0; } static inline int middle_conversion(struct dlm_lkb *lkb) { if ((lkb->lkb_grmode==DLM_LOCK_PR && lkb->lkb_rqmode==DLM_LOCK_CW) || (lkb->lkb_rqmode==DLM_LOCK_PR && lkb->lkb_grmode==DLM_LOCK_CW)) - return TRUE; - return FALSE; + return 1; + return 0; } static inline int down_conversion(struct dlm_lkb *lkb) @@ -269,7 +269,7 @@ static struct dlm_rsb *create_rsb(struct dlm_ls *ls, char *name, int len) r->res_ls = ls; r->res_length = len; memcpy(r->res_name, name, len); - init_MUTEX(&r->res_sem); + mutex_init(&r->res_mutex); INIT_LIST_HEAD(&r->res_lookup); INIT_LIST_HEAD(&r->res_grantqueue); @@ -712,7 +712,7 @@ static void add_to_waiters(struct dlm_lkb *lkb, int mstype) { struct dlm_ls *ls = lkb->lkb_resource->res_ls; - down(&ls->ls_waiters_sem); + mutex_lock(&ls->ls_waiters_mutex); if (lkb->lkb_wait_type) { log_print("add_to_waiters error %d", lkb->lkb_wait_type); goto out; @@ -721,7 +721,7 @@ static void add_to_waiters(struct dlm_lkb *lkb, int mstype) kref_get(&lkb->lkb_ref); list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); out: - up(&ls->ls_waiters_sem); + mutex_unlock(&ls->ls_waiters_mutex); } static int _remove_from_waiters(struct dlm_lkb *lkb) @@ -745,9 +745,9 @@ static int remove_from_waiters(struct dlm_lkb *lkb) struct dlm_ls *ls = lkb->lkb_resource->res_ls; int error; - down(&ls->ls_waiters_sem); + mutex_lock(&ls->ls_waiters_mutex); error = _remove_from_waiters(lkb); - up(&ls->ls_waiters_sem); + mutex_unlock(&ls->ls_waiters_mutex); return error; } @@ -775,14 +775,14 @@ static int shrink_bucket(struct dlm_ls *ls, int b) int count = 0, found; for (;;) { - found = FALSE; + found = 0; write_lock(&ls->ls_rsbtbl[b].lock); list_for_each_entry_reverse(r, &ls->ls_rsbtbl[b].toss, res_hashchain) { if (!time_after_eq(jiffies, r->res_toss_time + dlm_config.toss_secs * HZ)) continue; - found = TRUE; + found = 1; break; } @@ -1027,9 +1027,9 @@ static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head) struct dlm_lkb *first = list_entry(head->next, struct dlm_lkb, lkb_statequeue); if (lkb->lkb_id == first->lkb_id) - return TRUE; + return 1; - return FALSE; + return 0; } /* Return 1 if the locks' ranges overlap. If the lkb has no range then it is @@ -1038,13 +1038,13 @@ static inline int first_in_list(struct dlm_lkb *lkb, struct list_head *head) static inline int ranges_overlap(struct dlm_lkb *lkb1, struct dlm_lkb *lkb2) { if (!lkb1->lkb_range || !lkb2->lkb_range) - return TRUE; + return 1; if (lkb1->lkb_range[RQ_RANGE_END] < lkb2->lkb_range[GR_RANGE_START] || lkb1->lkb_range[RQ_RANGE_START] > lkb2->lkb_range[GR_RANGE_END]) - return FALSE; + return 0; - return TRUE; + return 1; } /* Check if the given lkb conflicts with another lkb on the queue. */ @@ -1057,9 +1057,9 @@ static int queue_conflict(struct list_head *head, struct dlm_lkb *lkb) if (this == lkb) continue; if (ranges_overlap(lkb, this) && !modes_compat(this, lkb)) - return TRUE; + return 1; } - return FALSE; + return 0; } /* @@ -1103,7 +1103,7 @@ static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) continue; if (!modes_compat(this, lkb) && !modes_compat(lkb, this)) - return TRUE; + return 1; } /* if lkb is on the convert queue and is preventing the first @@ -1114,10 +1114,10 @@ static int conversion_deadlock_detect(struct dlm_rsb *rsb, struct dlm_lkb *lkb) if (self && self != first) { if (!modes_compat(lkb, first) && !queue_conflict(&rsb->res_grantqueue, first)) - return TRUE; + return 1; } - return FALSE; + return 0; } /* @@ -1157,7 +1157,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) */ if (lkb->lkb_exflags & DLM_LKF_EXPEDITE) - return TRUE; + return 1; /* * A shortcut. Without this, !queue_conflict(grantqueue, lkb) would be @@ -1200,7 +1200,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) */ if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT)) - return TRUE; + return 1; /* * When using range locks the NOORDER flag is set to avoid the standard @@ -1208,7 +1208,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) */ if (lkb->lkb_exflags & DLM_LKF_NOORDER) - return TRUE; + return 1; /* * 6-3: Once in that queue [CONVERTING], a conversion request cannot be @@ -1217,7 +1217,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) */ if (!now && conv && first_in_list(lkb, &r->res_convertqueue)) - return TRUE; + return 1; /* * 6-4: By default, a new request is immediately granted only if all @@ -1232,7 +1232,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (now && !conv && list_empty(&r->res_convertqueue) && list_empty(&r->res_waitqueue)) - return TRUE; + return 1; /* * 6-4: Once a lock request is in the queue of ungranted new requests, @@ -1244,7 +1244,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (!now && !conv && list_empty(&r->res_convertqueue) && first_in_list(lkb, &r->res_waitqueue)) - return TRUE; + return 1; out: /* @@ -1257,7 +1257,7 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) lkb->lkb_sbflags |= DLM_SBF_DEMOTED; } - return FALSE; + return 0; } /* @@ -1308,7 +1308,7 @@ static int grant_pending_convert(struct dlm_rsb *r, int high) list_for_each_entry_safe(lkb, s, &r->res_convertqueue, lkb_statequeue) { demoted = is_demoted(lkb); - if (can_be_granted(r, lkb, FALSE)) { + if (can_be_granted(r, lkb, 0)) { grant_lock_pending(r, lkb); grant_restart = 1; } else { @@ -1333,7 +1333,7 @@ static int grant_pending_wait(struct dlm_rsb *r, int high) struct dlm_lkb *lkb, *s; list_for_each_entry_safe(lkb, s, &r->res_waitqueue, lkb_statequeue) { - if (can_be_granted(r, lkb, FALSE)) + if (can_be_granted(r, lkb, 0)) grant_lock_pending(r, lkb); else high = max_t(int, lkb->lkb_rqmode, high); @@ -1705,7 +1705,7 @@ static int do_request(struct dlm_rsb *r, struct dlm_lkb *lkb) { int error = 0; - if (can_be_granted(r, lkb, TRUE)) { + if (can_be_granted(r, lkb, 1)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); goto out; @@ -1733,7 +1733,7 @@ static int do_convert(struct dlm_rsb *r, struct dlm_lkb *lkb) /* changing an existing lock may allow others to be granted */ - if (can_be_granted(r, lkb, TRUE)) { + if (can_be_granted(r, lkb, 1)) { grant_lock(r, lkb); queue_cast(r, lkb, 0); grant_pending_locks(r); @@ -2556,7 +2556,7 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms) { struct dlm_lkb *lkb; struct dlm_rsb *r; - int error, reply = TRUE; + int error, reply = 1; error = find_lkb(ls, ms->m_remid, &lkb); if (error) @@ -3205,7 +3205,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) { struct dlm_lkb *lkb, *safe; - down(&ls->ls_waiters_sem); + mutex_lock(&ls->ls_waiters_mutex); list_for_each_entry_safe(lkb, safe, &ls->ls_waiters, lkb_wait_reply) { log_debug(ls, "pre recover waiter lkid %x type %d flags %x", @@ -3253,7 +3253,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) lkb->lkb_wait_type); } } - up(&ls->ls_waiters_sem); + mutex_unlock(&ls->ls_waiters_mutex); } static int remove_resend_waiter(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) @@ -3261,7 +3261,7 @@ static int remove_resend_waiter(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) struct dlm_lkb *lkb; int rv = 0; - down(&ls->ls_waiters_sem); + mutex_lock(&ls->ls_waiters_mutex); list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) { if (lkb->lkb_flags & DLM_IFL_RESEND) { rv = lkb->lkb_wait_type; @@ -3270,7 +3270,7 @@ static int remove_resend_waiter(struct dlm_ls *ls, struct dlm_lkb **lkb_ret) break; } } - up(&ls->ls_waiters_sem); + mutex_unlock(&ls->ls_waiters_mutex); if (!rv) lkb = NULL; diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 9e6499f773da77..bffab9c88b1daf 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h @@ -38,12 +38,12 @@ static inline int is_master(struct dlm_rsb *r) static inline void lock_rsb(struct dlm_rsb *r) { - down(&r->res_sem); + mutex_lock(&r->res_mutex); } static inline void unlock_rsb(struct dlm_rsb *r) { - up(&r->res_sem); + mutex_unlock(&r->res_mutex); } #endif diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index fee4659b6582f2..d2ff505d51cd45 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -31,7 +31,7 @@ static inline void dlm_delete_debug_file(struct dlm_ls *ls) { } #endif static int ls_count; -static struct semaphore ls_lock; +static struct mutex ls_lock; static struct list_head lslist; static spinlock_t lslist_lock; static struct task_struct * scand_task; @@ -177,7 +177,7 @@ int dlm_lockspace_init(void) int error; ls_count = 0; - init_MUTEX(&ls_lock); + mutex_init(&ls_lock); INIT_LIST_HEAD(&lslist); spin_lock_init(&lslist_lock); @@ -351,10 +351,9 @@ static int new_lockspace(char *name, int namelen, void **lockspace, return -EEXIST; } - ls = kmalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL); + ls = kzalloc(sizeof(struct dlm_ls) + namelen, GFP_KERNEL); if (!ls) goto out; - memset(ls, 0, sizeof(struct dlm_ls) + namelen); memcpy(ls->ls_name, name, namelen); ls->ls_namelen = namelen; ls->ls_exflags = flags; @@ -398,7 +397,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, } INIT_LIST_HEAD(&ls->ls_waiters); - init_MUTEX(&ls->ls_waiters_sem); + mutex_init(&ls->ls_waiters_mutex); INIT_LIST_HEAD(&ls->ls_nodes); INIT_LIST_HEAD(&ls->ls_nodes_gone); @@ -416,14 +415,14 @@ static int new_lockspace(char *name, int namelen, void **lockspace, ls->ls_uevent_result = 0; ls->ls_recoverd_task = NULL; - init_MUTEX(&ls->ls_recoverd_active); + mutex_init(&ls->ls_recoverd_active); spin_lock_init(&ls->ls_recover_lock); ls->ls_recover_status = 0; ls->ls_recover_seq = 0; ls->ls_recover_args = NULL; init_rwsem(&ls->ls_in_recovery); INIT_LIST_HEAD(&ls->ls_requestqueue); - init_MUTEX(&ls->ls_requestqueue_lock); + mutex_init(&ls->ls_requestqueue_mutex); ls->ls_recover_buf = kmalloc(dlm_config.buffer_size, GFP_KERNEL); if (!ls->ls_recover_buf) @@ -493,7 +492,7 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace, { int error = 0; - down(&ls_lock); + mutex_lock(&ls_lock); if (!ls_count) error = threads_start(); if (error) @@ -503,7 +502,7 @@ int dlm_new_lockspace(char *name, int namelen, void **lockspace, if (!error) ls_count++; out: - up(&ls_lock); + mutex_unlock(&ls_lock); return error; } @@ -629,11 +628,11 @@ static int release_lockspace(struct dlm_ls *ls, int force) kobject_unregister(&ls->ls_kobj); kfree(ls); - down(&ls_lock); + mutex_lock(&ls_lock); ls_count--; if (!ls_count) threads_stop(); - up(&ls_lock); + mutex_unlock(&ls_lock); module_put(THIS_MODULE); return 0; diff --git a/fs/dlm/member.c b/fs/dlm/member.c index 439249b62a574a..926cd0cb6bffff 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -52,7 +52,7 @@ static int dlm_add_member(struct dlm_ls *ls, int nodeid) struct dlm_member *memb; int w; - memb = kmalloc(sizeof(struct dlm_member), GFP_KERNEL); + memb = kzalloc(sizeof(struct dlm_member), GFP_KERNEL); if (!memb) return -ENOMEM; @@ -79,9 +79,9 @@ static int dlm_is_member(struct dlm_ls *ls, int nodeid) list_for_each_entry(memb, &ls->ls_nodes, list) { if (memb->nodeid == nodeid) - return TRUE; + return 1; } - return FALSE; + return 0; } int dlm_is_removed(struct dlm_ls *ls, int nodeid) @@ -90,9 +90,9 @@ int dlm_is_removed(struct dlm_ls *ls, int nodeid) list_for_each_entry(memb, &ls->ls_nodes_gone, list) { if (memb->nodeid == nodeid) - return TRUE; + return 1; } - return FALSE; + return 0; } static void clear_memb_list(struct list_head *head) @@ -178,10 +178,10 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) /* move departed members from ls_nodes to ls_nodes_gone */ list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { - found = FALSE; + found = 0; for (i = 0; i < rv->node_count; i++) { if (memb->nodeid == rv->nodeids[i]) { - found = TRUE; + found = 1; break; } } @@ -271,10 +271,9 @@ int dlm_ls_start(struct dlm_ls *ls) int *ids = NULL; int error, count; - rv = kmalloc(sizeof(struct dlm_recover), GFP_KERNEL); + rv = kzalloc(sizeof(struct dlm_recover), GFP_KERNEL); if (!rv) return -ENOMEM; - memset(rv, 0, sizeof(struct dlm_recover)); error = count = dlm_nodeid_list(ls->ls_name, &ids); if (error <= 0) diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c index d96f9bbb407c4f..c9b1c3d535f4c0 100644 --- a/fs/dlm/midcomms.c +++ b/fs/dlm/midcomms.c @@ -119,7 +119,7 @@ int dlm_process_incoming_buffer(int nodeid, const void *base, switch (msg->h_cmd) { case DLM_MSG: - dlm_receive_message(msg, nodeid, FALSE); + dlm_receive_message(msg, nodeid, 0); break; case DLM_RCOM: diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index 1712c97bc22937..b036ee7dcb32ae 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c @@ -420,7 +420,7 @@ int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc) r = recover_list_find(ls, rc->rc_id); if (!r) { - log_error(ls, "dlm_recover_master_reply no id %"PRIx64"", + log_error(ls, "dlm_recover_master_reply no id %llx", rc->rc_id); goto out; } @@ -477,8 +477,8 @@ static int all_queues_empty(struct dlm_rsb *r) if (!list_empty(&r->res_grantqueue) || !list_empty(&r->res_convertqueue) || !list_empty(&r->res_waitqueue)) - return FALSE; - return TRUE; + return 0; + return 1; } static int recover_locks(struct dlm_rsb *r) @@ -586,18 +586,18 @@ static void recover_lvb(struct dlm_rsb *r) { struct dlm_lkb *lkb, *high_lkb = NULL; uint32_t high_seq = 0; - int lock_lvb_exists = FALSE; - int big_lock_exists = FALSE; + int lock_lvb_exists = 0; + int big_lock_exists = 0; int lvblen = r->res_ls->ls_lvblen; list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) { if (!(lkb->lkb_exflags & DLM_LKF_VALBLK)) continue; - lock_lvb_exists = TRUE; + lock_lvb_exists = 1; if (lkb->lkb_grmode > DLM_LOCK_CR) { - big_lock_exists = TRUE; + big_lock_exists = 1; goto setflag; } @@ -611,10 +611,10 @@ static void recover_lvb(struct dlm_rsb *r) if (!(lkb->lkb_exflags & DLM_LKF_VALBLK)) continue; - lock_lvb_exists = TRUE; + lock_lvb_exists = 1; if (lkb->lkb_grmode > DLM_LOCK_CR) { - big_lock_exists = TRUE; + big_lock_exists = 1; goto setflag; } diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 06e4f7cab6e774..70103533677d91 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c @@ -45,9 +45,9 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) unsigned long start; int error, neg = 0; - log_debug(ls, "recover %"PRIx64"", rv->seq); + log_debug(ls, "recover %llx", rv->seq); - down(&ls->ls_recoverd_active); + mutex_lock(&ls->ls_recoverd_active); /* * Suspending and resuming dlm_astd ensures that no lkb's from this ls @@ -199,16 +199,16 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) dlm_astd_wake(); - log_debug(ls, "recover %"PRIx64" done: %u ms", rv->seq, + log_debug(ls, "recover %llx done: %u ms", rv->seq, jiffies_to_msecs(jiffies - start)); - up(&ls->ls_recoverd_active); + mutex_unlock(&ls->ls_recoverd_active); return 0; fail: dlm_release_root_list(ls); - log_debug(ls, "recover %"PRIx64" error %d", rv->seq, error); - up(&ls->ls_recoverd_active); + log_debug(ls, "recover %llx error %d", rv->seq, error); + mutex_unlock(&ls->ls_recoverd_active); return error; } @@ -275,11 +275,11 @@ void dlm_recoverd_stop(struct dlm_ls *ls) void dlm_recoverd_suspend(struct dlm_ls *ls) { - down(&ls->ls_recoverd_active); + mutex_lock(&ls->ls_recoverd_active); } void dlm_recoverd_resume(struct dlm_ls *ls) { - up(&ls->ls_recoverd_active); + mutex_unlock(&ls->ls_recoverd_active); } diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 36afe99e4f93e1..7b2b089634a2df 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c @@ -47,9 +47,9 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) e->nodeid = nodeid; memcpy(e->request, hd, length); - down(&ls->ls_requestqueue_lock); + mutex_lock(&ls->ls_requestqueue_mutex); list_add_tail(&e->list, &ls->ls_requestqueue); - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); } int dlm_process_requestqueue(struct dlm_ls *ls) @@ -58,19 +58,19 @@ int dlm_process_requestqueue(struct dlm_ls *ls) struct dlm_header *hd; int error = 0; - down(&ls->ls_requestqueue_lock); + mutex_lock(&ls->ls_requestqueue_mutex); for (;;) { if (list_empty(&ls->ls_requestqueue)) { - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); error = 0; break; } e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); hd = (struct dlm_header *) e->request; - error = dlm_receive_message(hd, e->nodeid, TRUE); + error = dlm_receive_message(hd, e->nodeid, 1); if (error == -EINTR) { /* entry is left on requestqueue */ @@ -78,13 +78,13 @@ int dlm_process_requestqueue(struct dlm_ls *ls) break; } - down(&ls->ls_requestqueue_lock); + mutex_lock(&ls->ls_requestqueue_mutex); list_del(&e->list); kfree(e); if (dlm_locking_stopped(ls)) { log_debug(ls, "process_requestqueue abort running"); - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); error = -EINTR; break; } @@ -105,15 +105,15 @@ int dlm_process_requestqueue(struct dlm_ls *ls) void dlm_wait_requestqueue(struct dlm_ls *ls) { for (;;) { - down(&ls->ls_requestqueue_lock); + mutex_lock(&ls->ls_requestqueue_mutex); if (list_empty(&ls->ls_requestqueue)) break; if (dlm_locking_stopped(ls)) break; - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); schedule(); } - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); } static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) @@ -170,7 +170,7 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) struct dlm_message *ms; struct rq_entry *e, *safe; - down(&ls->ls_requestqueue_lock); + mutex_lock(&ls->ls_requestqueue_mutex); list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { ms = (struct dlm_message *) e->request; @@ -179,6 +179,6 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) kfree(e); } } - up(&ls->ls_requestqueue_lock); + mutex_unlock(&ls->ls_requestqueue_mutex); } -- cgit 1.2.3-korg From 1c032c03117c014512195f2e33c3af999f132146 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 28 Apr 2006 10:50:41 -0400 Subject: [DLM] PATCH 2/3 dlm: lowcomms close When a node is removed from a lockspace configuration, close our connection to it, clearing any remaining messages for it. Signed-off-by: David Teigland Signed-off-by: Patrick Caulfield Signed-off-by: Steven Whitehouse --- fs/dlm/config.c | 2 ++ fs/dlm/lowcomms.c | 21 +++++++++++++++++++++ fs/dlm/lowcomms.h | 1 + fs/dlm/member.c | 1 - 4 files changed, 24 insertions(+), 1 deletion(-) (limited to 'fs/dlm/member.c') diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 87df9616415e5d..88553054bbfa4c 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -17,6 +17,7 @@ #include #include "config.h" +#include "lowcomms.h" /* * /config/dlm//spaces//nodes//nodeid @@ -429,6 +430,7 @@ static void drop_comm(struct config_group *g, struct config_item *i) struct comm *cm = to_comm(i); if (local_comm == cm) local_comm = NULL; + dlm_lowcomms_close(cm->nodeid); while (cm->addr_count--) kfree(cm->addr[cm->addr_count]); config_item_put(i); diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 09b0124f7fc41c..cdd168e4bf450c 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1063,6 +1063,27 @@ static void dealloc_nodeinfo(void) } } +int dlm_lowcomms_close(int nodeid) +{ + struct nodeinfo *ni; + + ni = nodeid2nodeinfo(nodeid, 0); + if (!ni) + return -1; + + spin_lock(&ni->lock); + if (ni->assoc_id) { + ni->assoc_id = 0; + /* Don't send shutdown here, sctp will just queue it + till the node comes back up! */ + } + spin_unlock(&ni->lock); + + clean_one_writequeue(ni); + clear_bit(NI_INIT_PENDING, &ni->flags); + return 0; +} + static int write_list_empty(void) { int status; diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h index 3af8035ff12fcd..6c04bb09cfa8dc 100644 --- a/fs/dlm/lowcomms.h +++ b/fs/dlm/lowcomms.h @@ -18,6 +18,7 @@ int dlm_lowcomms_init(void); void dlm_lowcomms_exit(void); int dlm_lowcomms_start(void); void dlm_lowcomms_stop(void); +int dlm_lowcomms_close(int nodeid); void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc); void dlm_lowcomms_commit_buffer(void *mh); diff --git a/fs/dlm/member.c b/fs/dlm/member.c index 926cd0cb6bffff..cd0c51e724e07a 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -15,7 +15,6 @@ #include "member.h" #include "recoverd.h" #include "recover.h" -#include "lowcomms.h" #include "rcom.h" #include "config.h" -- cgit 1.2.3-korg From f6db1b8e724b071d144055b48da3827ce26dba1c Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 8 Aug 2006 17:06:07 -0500 Subject: [DLM] abort recovery more quickly When we abort one recovery to do another, break out of the ping_members() routine more quickly, and wake up the dlm_recoverd thread more quickly instead of waiting for it to time out. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/member.c | 24 +++++++++++++++++++----- fs/dlm/recoverd.c | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'fs/dlm/member.c') diff --git a/fs/dlm/member.c b/fs/dlm/member.c index cd0c51e724e07a..ebb33c30f0f352 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -162,11 +162,22 @@ static void make_member_array(struct dlm_ls *ls) /* send a status request to all members just to establish comms connections */ -static void ping_members(struct dlm_ls *ls) +static int ping_members(struct dlm_ls *ls) { struct dlm_member *memb; - list_for_each_entry(memb, &ls->ls_nodes, list) - dlm_rcom_status(ls, memb->nodeid); + int error = 0; + + list_for_each_entry(memb, &ls->ls_nodes, list) { + error = dlm_recovery_stopped(ls); + if (error) + break; + error = dlm_rcom_status(ls, memb->nodeid); + if (error) + break; + } + if (error) + log_debug(ls, "ping_members aborted %d", error); + return error; } int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) @@ -212,10 +223,13 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) dlm_set_recover_status(ls, DLM_RS_NODES); *neg_out = neg; - ping_members(ls); + error = ping_members(ls); + if (error) + goto out; error = dlm_recover_members_wait(ls); - log_debug(ls, "total members %d", ls->ls_num_nodes); + out: + log_debug(ls, "total members %d error %d", ls->ls_num_nodes, error); return error; } diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 70103533677d91..eac8e9fa67f13c 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c @@ -275,6 +275,7 @@ void dlm_recoverd_stop(struct dlm_ls *ls) void dlm_recoverd_suspend(struct dlm_ls *ls) { + wake_up(&ls->ls_wait_general); mutex_lock(&ls->ls_recoverd_active); } -- cgit 1.2.3-korg From faa0f2677287a2e7ae796db8b73618ec43715e94 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 8 Aug 2006 17:08:42 -0500 Subject: [DLM] show nodeid for recovery message To aid debugging, it's useful to be able to see what nodeid the dlm is waiting on for a message reply. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/dlm/dlm_internal.h | 1 + fs/dlm/lockspace.c | 11 +++++++++++ fs/dlm/member.c | 3 ++- fs/dlm/rcom.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) (limited to 'fs/dlm/member.c') diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 7c3c2d27c012c3..ec7e401133fd6c 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -467,6 +467,7 @@ struct dlm_ls { struct list_head ls_requestqueue;/* queue remote requests */ struct mutex ls_requestqueue_mutex; char *ls_recover_buf; + int ls_recover_nodeid; /* for debugging */ struct list_head ls_recover_list; spinlock_t ls_recover_list_lock; int ls_recover_list_count; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 31ed0fe16a3161..7adaad53fc3830 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -81,6 +81,11 @@ static ssize_t dlm_recover_status_show(struct dlm_ls *ls, char *buf) return sprintf(buf, "%x\n", status); } +static ssize_t dlm_recover_nodeid_show(struct dlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->ls_recover_nodeid); +} + struct dlm_attr { struct attribute attr; ssize_t (*show)(struct dlm_ls *, char *); @@ -108,11 +113,17 @@ static struct dlm_attr dlm_attr_recover_status = { .show = dlm_recover_status_show }; +static struct dlm_attr dlm_attr_recover_nodeid = { + .attr = {.name = "recover_nodeid", .mode = S_IRUGO}, + .show = dlm_recover_nodeid_show +}; + static struct attribute *dlm_attrs[] = { &dlm_attr_control.attr, &dlm_attr_event.attr, &dlm_attr_id.attr, &dlm_attr_recover_status.attr, + &dlm_attr_recover_nodeid.attr, NULL, }; diff --git a/fs/dlm/member.c b/fs/dlm/member.c index ebb33c30f0f352..a3f7de7f3a8f96 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -176,7 +176,8 @@ static int ping_members(struct dlm_ls *ls) break; } if (error) - log_debug(ls, "ping_members aborted %d", error); + log_debug(ls, "ping_members aborted %d last nodeid %d", + error, ls->ls_recover_nodeid); return error; } diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 55fbe313340e59..5573d8590e588d 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c @@ -97,6 +97,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) int error = 0; memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); + ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { rc = (struct dlm_rcom *) ls->ls_recover_buf; @@ -159,6 +160,7 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) int error = 0, len = sizeof(struct dlm_rcom); memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); + ls->ls_recover_nodeid = nodeid; if (nodeid == dlm_our_nodeid()) { dlm_copy_master_names(ls, last_name, last_len, -- cgit 1.2.3-korg