Commit 659b3613 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'dlm-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm

Pull dlm updates from David Teigland:

 - Allow blocking posix lock requests to be interrupted while waiting.
   This requires a cancel request to be sent to the userspace daemon
   where posix lock requests are processed across the cluster.

 - Fix a posix lock patch from the previous cycle in which lock requests
   from different file systems could be mixed up.

 - Fix some long standing problems with nfs posix lock cancelation.

 - Add a new debugfs file for printing queued callbacks.

 - Stop modifying buffers that have been used to receive a message.

 - Misc cleanups and some refactoring.

* tag 'dlm-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
  dlm: fix plock lookup when using multiple lockspaces
  fs: dlm: don't use RCOM_NAMES for version detection
  fs: dlm: create midcomms nodes when configure
  fs: dlm: constify receive buffer
  fs: dlm: drop rxbuf manipulation in dlm_recover_master_copy
  fs: dlm: drop rxbuf manipulation in dlm_copy_master_names
  fs: dlm: get recovery sequence number as parameter
  fs: dlm: cleanup lock order
  fs: dlm: remove clear_members_cb
  fs: dlm: add plock dev tracepoints
  fs: dlm: check on plock ops when exit dlm
  fs: dlm: debugfs for queued callbacks
  fs: dlm: remove unused processed_nodes
  fs: dlm: add missing spin_unlock
  fs: dlm: fix F_CANCELLK to cancel pending request
  fs: dlm: allow to F_SETLKW getting interrupted
  fs: dlm: remove twice newline
parents e7e9423d 7c53e847
...@@ -664,7 +664,7 @@ static ssize_t comm_addr_store(struct config_item *item, const char *buf, ...@@ -664,7 +664,7 @@ static ssize_t comm_addr_store(struct config_item *item, const char *buf,
memcpy(addr, buf, len); memcpy(addr, buf, len);
rv = dlm_lowcomms_addr(cm->nodeid, addr, len); rv = dlm_midcomms_addr(cm->nodeid, addr, len);
if (rv) { if (rv) {
kfree(addr); kfree(addr);
return rv; return rv;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "dlm_internal.h" #include "dlm_internal.h"
#include "midcomms.h" #include "midcomms.h"
#include "lock.h" #include "lock.h"
#include "ast.h"
#define DLM_DEBUG_BUF_LEN 4096 #define DLM_DEBUG_BUF_LEN 4096
static char debug_buf[DLM_DEBUG_BUF_LEN]; static char debug_buf[DLM_DEBUG_BUF_LEN];
...@@ -365,6 +366,52 @@ static void print_format4(struct dlm_rsb *r, struct seq_file *s) ...@@ -365,6 +366,52 @@ static void print_format4(struct dlm_rsb *r, struct seq_file *s)
unlock_rsb(r); unlock_rsb(r);
} }
static void print_format5_lock(struct seq_file *s, struct dlm_lkb *lkb)
{
struct dlm_callback *cb;
/* lkb_id lkb_flags mode flags sb_status sb_flags */
spin_lock(&lkb->lkb_cb_lock);
list_for_each_entry(cb, &lkb->lkb_callbacks, list) {
seq_printf(s, "%x %x %d %x %d %x\n",
lkb->lkb_id,
dlm_iflags_val(lkb),
cb->mode,
cb->flags,
cb->sb_status,
cb->sb_flags);
}
spin_unlock(&lkb->lkb_cb_lock);
}
static void print_format5(struct dlm_rsb *r, struct seq_file *s)
{
struct dlm_lkb *lkb;
lock_rsb(r);
list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
print_format5_lock(s, lkb);
if (seq_has_overflowed(s))
goto out;
}
list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
print_format5_lock(s, lkb);
if (seq_has_overflowed(s))
goto out;
}
list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
print_format5_lock(s, lkb);
if (seq_has_overflowed(s))
goto out;
}
out:
unlock_rsb(r);
}
struct rsbtbl_iter { struct rsbtbl_iter {
struct dlm_rsb *rsb; struct dlm_rsb *rsb;
unsigned bucket; unsigned bucket;
...@@ -408,6 +455,13 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr) ...@@ -408,6 +455,13 @@ static int table_seq_show(struct seq_file *seq, void *iter_ptr)
} }
print_format4(ri->rsb, seq); print_format4(ri->rsb, seq);
break; break;
case 5:
if (ri->header) {
seq_puts(seq, "lkb_id lkb_flags mode flags sb_status sb_flags\n");
ri->header = 0;
}
print_format5(ri->rsb, seq);
break;
} }
return 0; return 0;
...@@ -417,6 +471,7 @@ static const struct seq_operations format1_seq_ops; ...@@ -417,6 +471,7 @@ static const struct seq_operations format1_seq_ops;
static const struct seq_operations format2_seq_ops; static const struct seq_operations format2_seq_ops;
static const struct seq_operations format3_seq_ops; static const struct seq_operations format3_seq_ops;
static const struct seq_operations format4_seq_ops; static const struct seq_operations format4_seq_ops;
static const struct seq_operations format5_seq_ops;
static void *table_seq_start(struct seq_file *seq, loff_t *pos) static void *table_seq_start(struct seq_file *seq, loff_t *pos)
{ {
...@@ -448,6 +503,8 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos) ...@@ -448,6 +503,8 @@ static void *table_seq_start(struct seq_file *seq, loff_t *pos)
ri->format = 3; ri->format = 3;
if (seq->op == &format4_seq_ops) if (seq->op == &format4_seq_ops)
ri->format = 4; ri->format = 4;
if (seq->op == &format5_seq_ops)
ri->format = 5;
tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep; tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
...@@ -602,10 +659,18 @@ static const struct seq_operations format4_seq_ops = { ...@@ -602,10 +659,18 @@ static const struct seq_operations format4_seq_ops = {
.show = table_seq_show, .show = table_seq_show,
}; };
static const struct seq_operations format5_seq_ops = {
.start = table_seq_start,
.next = table_seq_next,
.stop = table_seq_stop,
.show = table_seq_show,
};
static const struct file_operations format1_fops; static const struct file_operations format1_fops;
static const struct file_operations format2_fops; static const struct file_operations format2_fops;
static const struct file_operations format3_fops; static const struct file_operations format3_fops;
static const struct file_operations format4_fops; static const struct file_operations format4_fops;
static const struct file_operations format5_fops;
static int table_open1(struct inode *inode, struct file *file) static int table_open1(struct inode *inode, struct file *file)
{ {
...@@ -683,7 +748,21 @@ static int table_open4(struct inode *inode, struct file *file) ...@@ -683,7 +748,21 @@ static int table_open4(struct inode *inode, struct file *file)
struct seq_file *seq; struct seq_file *seq;
int ret; int ret;
ret = seq_open(file, &format4_seq_ops); ret = seq_open(file, &format5_seq_ops);
if (ret)
return ret;
seq = file->private_data;
seq->private = inode->i_private; /* the dlm_ls */
return 0;
}
static int table_open5(struct inode *inode, struct file *file)
{
struct seq_file *seq;
int ret;
ret = seq_open(file, &format5_seq_ops);
if (ret) if (ret)
return ret; return ret;
...@@ -725,6 +804,14 @@ static const struct file_operations format4_fops = { ...@@ -725,6 +804,14 @@ static const struct file_operations format4_fops = {
.release = seq_release .release = seq_release
}; };
static const struct file_operations format5_fops = {
.owner = THIS_MODULE,
.open = table_open5,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
/* /*
* dump lkb's on the ls_waiters list * dump lkb's on the ls_waiters list
*/ */
...@@ -793,6 +880,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls) ...@@ -793,6 +880,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls)
debugfs_remove(ls->ls_debug_locks_dentry); debugfs_remove(ls->ls_debug_locks_dentry);
debugfs_remove(ls->ls_debug_all_dentry); debugfs_remove(ls->ls_debug_all_dentry);
debugfs_remove(ls->ls_debug_toss_dentry); debugfs_remove(ls->ls_debug_toss_dentry);
debugfs_remove(ls->ls_debug_queued_asts_dentry);
} }
static int dlm_state_show(struct seq_file *file, void *offset) static int dlm_state_show(struct seq_file *file, void *offset)
...@@ -936,6 +1024,17 @@ void dlm_create_debug_file(struct dlm_ls *ls) ...@@ -936,6 +1024,17 @@ void dlm_create_debug_file(struct dlm_ls *ls)
dlm_root, dlm_root,
ls, ls,
&waiters_fops); &waiters_fops);
/* format 5 */
memset(name, 0, sizeof(name));
snprintf(name, DLM_LOCKSPACE_LEN + 8, "%s_queued_asts", ls->ls_name);
ls->ls_debug_queued_asts_dentry = debugfs_create_file(name,
0644,
dlm_root,
ls,
&format5_fops);
} }
void __init dlm_register_debugfs(void) void __init dlm_register_debugfs(void)
......
...@@ -58,7 +58,7 @@ void dlm_recover_dir_nodeid(struct dlm_ls *ls) ...@@ -58,7 +58,7 @@ void dlm_recover_dir_nodeid(struct dlm_ls *ls)
up_read(&ls->ls_root_sem); up_read(&ls->ls_root_sem);
} }
int dlm_recover_directory(struct dlm_ls *ls) int dlm_recover_directory(struct dlm_ls *ls, uint64_t seq)
{ {
struct dlm_member *memb; struct dlm_member *memb;
char *b, *last_name = NULL; char *b, *last_name = NULL;
...@@ -90,7 +90,7 @@ int dlm_recover_directory(struct dlm_ls *ls) ...@@ -90,7 +90,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
} }
error = dlm_rcom_names(ls, memb->nodeid, error = dlm_rcom_names(ls, memb->nodeid,
last_name, last_len); last_name, last_len, seq);
if (error) if (error)
goto out_free; goto out_free;
...@@ -196,7 +196,8 @@ int dlm_recover_directory(struct dlm_ls *ls) ...@@ -196,7 +196,8 @@ int dlm_recover_directory(struct dlm_ls *ls)
return error; return error;
} }
static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, const char *name,
int len)
{ {
struct dlm_rsb *r; struct dlm_rsb *r;
uint32_t hash, bucket; uint32_t hash, bucket;
...@@ -232,7 +233,7 @@ static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) ...@@ -232,7 +233,7 @@ static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
for rsb's we're master of and whose directory node matches the requesting for rsb's we're master of and whose directory node matches the requesting
node. inbuf is the rsb name last sent, inlen is the name's length */ node. inbuf is the rsb name last sent, inlen is the name's length */
void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, void dlm_copy_master_names(struct dlm_ls *ls, const char *inbuf, int inlen,
char *outbuf, int outlen, int nodeid) char *outbuf, int outlen, int nodeid)
{ {
struct list_head *list; struct list_head *list;
...@@ -245,9 +246,8 @@ void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, ...@@ -245,9 +246,8 @@ void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen,
if (inlen > 1) { if (inlen > 1) {
r = find_rsb_root(ls, inbuf, inlen); r = find_rsb_root(ls, inbuf, inlen);
if (!r) { if (!r) {
inbuf[inlen - 1] = '\0'; log_error(ls, "copy_master_names from %d start %d %.*s",
log_error(ls, "copy_master_names from %d start %d %s", nodeid, inlen, inlen, inbuf);
nodeid, inlen, inbuf);
goto out; goto out;
} }
list = r->res_root_list.next; list = r->res_root_list.next;
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
int dlm_dir_nodeid(struct dlm_rsb *rsb); int dlm_dir_nodeid(struct dlm_rsb *rsb);
int dlm_hash2nodeid(struct dlm_ls *ls, uint32_t hash); int dlm_hash2nodeid(struct dlm_ls *ls, uint32_t hash);
void dlm_recover_dir_nodeid(struct dlm_ls *ls); void dlm_recover_dir_nodeid(struct dlm_ls *ls);
int dlm_recover_directory(struct dlm_ls *ls); int dlm_recover_directory(struct dlm_ls *ls, uint64_t seq);
void dlm_copy_master_names(struct dlm_ls *ls, char *inbuf, int inlen, void dlm_copy_master_names(struct dlm_ls *ls, const char *inbuf, int inlen,
char *outbuf, int outlen, int nodeid); char *outbuf, int outlen, int nodeid);
#endif /* __DIR_DOT_H__ */ #endif /* __DIR_DOT_H__ */
...@@ -598,6 +598,7 @@ struct dlm_ls { ...@@ -598,6 +598,7 @@ struct dlm_ls {
struct dentry *ls_debug_locks_dentry; /* debugfs */ struct dentry *ls_debug_locks_dentry; /* debugfs */
struct dentry *ls_debug_all_dentry; /* debugfs */ struct dentry *ls_debug_all_dentry; /* debugfs */
struct dentry *ls_debug_toss_dentry; /* debugfs */ struct dentry *ls_debug_toss_dentry; /* debugfs */
struct dentry *ls_debug_queued_asts_dentry; /* debugfs */
wait_queue_head_t ls_uevent_wait; /* user part of join/leave */ wait_queue_head_t ls_uevent_wait; /* user part of join/leave */
int ls_uevent_result; int ls_uevent_result;
......
This diff is collapsed.
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
#define __LOCK_DOT_H__ #define __LOCK_DOT_H__
void dlm_dump_rsb(struct dlm_rsb *r); void dlm_dump_rsb(struct dlm_rsb *r);
void dlm_dump_rsb_name(struct dlm_ls *ls, char *name, int len); void dlm_dump_rsb_name(struct dlm_ls *ls, const char *name, int len);
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, const struct dlm_message *ms,
uint32_t saved_seq); uint32_t saved_seq);
void dlm_receive_buffer(union dlm_packet *p, int nodeid); void dlm_receive_buffer(const union dlm_packet *p, int nodeid);
int dlm_modes_compat(int mode1, int mode2); int dlm_modes_compat(int mode1, int mode2);
void dlm_put_rsb(struct dlm_rsb *r); void dlm_put_rsb(struct dlm_rsb *r);
void dlm_hold_rsb(struct dlm_rsb *r); void dlm_hold_rsb(struct dlm_rsb *r);
...@@ -25,8 +25,8 @@ void dlm_scan_rsbs(struct dlm_ls *ls); ...@@ -25,8 +25,8 @@ void dlm_scan_rsbs(struct dlm_ls *ls);
int dlm_lock_recovery_try(struct dlm_ls *ls); int dlm_lock_recovery_try(struct dlm_ls *ls);
void dlm_unlock_recovery(struct dlm_ls *ls); void dlm_unlock_recovery(struct dlm_ls *ls);
int dlm_master_lookup(struct dlm_ls *ls, int nodeid, char *name, int len, int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,
unsigned int flags, int *r_nodeid, int *result); int len, unsigned int flags, int *r_nodeid, int *result);
int dlm_search_rsb_tree(struct rb_root *tree, const void *name, int len, int dlm_search_rsb_tree(struct rb_root *tree, const void *name, int len,
struct dlm_rsb **r_ret); struct dlm_rsb **r_ret);
...@@ -36,8 +36,10 @@ void dlm_purge_mstcpy_locks(struct dlm_rsb *r); ...@@ -36,8 +36,10 @@ void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
void dlm_recover_grant(struct dlm_ls *ls); void dlm_recover_grant(struct dlm_ls *ls);
int dlm_recover_waiters_post(struct dlm_ls *ls); int dlm_recover_waiters_post(struct dlm_ls *ls);
void dlm_recover_waiters_pre(struct dlm_ls *ls); void dlm_recover_waiters_pre(struct dlm_ls *ls);
int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc); int dlm_recover_master_copy(struct dlm_ls *ls, const struct dlm_rcom *rc,
int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc); __le32 *rl_remid, __le32 *rl_result);
int dlm_recover_process_copy(struct dlm_ls *ls, const struct dlm_rcom *rc,
uint64_t seq);
int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode, int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua, int mode,
uint32_t flags, void *name, unsigned int namelen); uint32_t flags, void *name, unsigned int namelen);
......
...@@ -863,7 +863,6 @@ struct dlm_processed_nodes { ...@@ -863,7 +863,6 @@ struct dlm_processed_nodes {
static void process_dlm_messages(struct work_struct *work) static void process_dlm_messages(struct work_struct *work)
{ {
struct processqueue_entry *pentry; struct processqueue_entry *pentry;
LIST_HEAD(processed_nodes);
spin_lock(&processqueue_lock); spin_lock(&processqueue_lock);
pentry = list_first_entry_or_null(&processqueue, pentry = list_first_entry_or_null(&processqueue,
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "midcomms.h" #include "midcomms.h"
#include "lowcomms.h" #include "lowcomms.h"
int dlm_slots_version(struct dlm_header *h) int dlm_slots_version(const struct dlm_header *h)
{ {
if ((le32_to_cpu(h->h_version) & 0x0000FFFF) < DLM_HEADER_SLOTS) if ((le32_to_cpu(h->h_version) & 0x0000FFFF) < DLM_HEADER_SLOTS)
return 0; return 0;
...@@ -393,14 +393,9 @@ static void remove_remote_member(int nodeid) ...@@ -393,14 +393,9 @@ static void remove_remote_member(int nodeid)
dlm_midcomms_remove_member(nodeid); dlm_midcomms_remove_member(nodeid);
} }
static void clear_members_cb(int nodeid)
{
remove_remote_member(nodeid);
}
void dlm_clear_members(struct dlm_ls *ls) void dlm_clear_members(struct dlm_ls *ls)
{ {
clear_memb_list(&ls->ls_nodes, clear_members_cb); clear_memb_list(&ls->ls_nodes, remove_remote_member);
ls->ls_num_nodes = 0; ls->ls_num_nodes = 0;
} }
...@@ -454,7 +449,7 @@ static void make_member_array(struct dlm_ls *ls) ...@@ -454,7 +449,7 @@ static void make_member_array(struct dlm_ls *ls)
/* send a status request to all members just to establish comms connections */ /* send a status request to all members just to establish comms connections */
static int ping_members(struct dlm_ls *ls) static int ping_members(struct dlm_ls *ls, uint64_t seq)
{ {
struct dlm_member *memb; struct dlm_member *memb;
int error = 0; int error = 0;
...@@ -464,7 +459,7 @@ static int ping_members(struct dlm_ls *ls) ...@@ -464,7 +459,7 @@ static int ping_members(struct dlm_ls *ls)
error = -EINTR; error = -EINTR;
break; break;
} }
error = dlm_rcom_status(ls, memb->nodeid, 0); error = dlm_rcom_status(ls, memb->nodeid, 0, seq);
if (error) if (error)
break; break;
} }
...@@ -612,7 +607,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) ...@@ -612,7 +607,7 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out)
make_member_array(ls); make_member_array(ls);
*neg_out = neg; *neg_out = neg;
error = ping_members(ls); error = ping_members(ls, rv->seq);
log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes); log_rinfo(ls, "dlm_recover_members %d nodes", ls->ls_num_nodes);
return error; return error;
} }
......
...@@ -18,7 +18,7 @@ void dlm_clear_members_gone(struct dlm_ls *ls); ...@@ -18,7 +18,7 @@ void dlm_clear_members_gone(struct dlm_ls *ls);
int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out); int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv,int *neg_out);
int dlm_is_removed(struct dlm_ls *ls, int nodeid); int dlm_is_removed(struct dlm_ls *ls, int nodeid);
int dlm_is_member(struct dlm_ls *ls, int nodeid); int dlm_is_member(struct dlm_ls *ls, int nodeid);
int dlm_slots_version(struct dlm_header *h); int dlm_slots_version(const struct dlm_header *h);
void dlm_slot_save(struct dlm_ls *ls, struct dlm_rcom *rc, void dlm_slot_save(struct dlm_ls *ls, struct dlm_rcom *rc,
struct dlm_member *memb); struct dlm_member *memb);
void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc); void dlm_slots_copy_out(struct dlm_ls *ls, struct dlm_rcom *rc);
......
This diff is collapsed.
...@@ -20,6 +20,7 @@ struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len, ...@@ -20,6 +20,7 @@ struct dlm_mhandle *dlm_midcomms_get_mhandle(int nodeid, int len,
gfp_t allocation, char **ppc); gfp_t allocation, char **ppc);
void dlm_midcomms_commit_mhandle(struct dlm_mhandle *mh, const void *name, void dlm_midcomms_commit_mhandle(struct dlm_mhandle *mh, const void *name,
int namelen); int namelen);
int dlm_midcomms_addr(int nodeid, struct sockaddr_storage *addr, int len);
void dlm_midcomms_version_wait(void); void dlm_midcomms_version_wait(void);
int dlm_midcomms_close(int nodeid); int dlm_midcomms_close(int nodeid);
int dlm_midcomms_start(void); int dlm_midcomms_start(void);
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/dlm_plock.h> #include <linux/dlm_plock.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <trace/events/dlm.h>
#include "dlm_internal.h" #include "dlm_internal.h"
#include "lockspace.h" #include "lockspace.h"
...@@ -42,6 +44,27 @@ static inline void set_version(struct dlm_plock_info *info) ...@@ -42,6 +44,27 @@ static inline void set_version(struct dlm_plock_info *info)
info->version[2] = DLM_PLOCK_VERSION_PATCH; info->version[2] = DLM_PLOCK_VERSION_PATCH;
} }
static struct plock_op *plock_lookup_waiter(const struct dlm_plock_info *info)
{
struct plock_op *op = NULL, *iter;
list_for_each_entry(iter, &recv_list, list) {
if (iter->info.fsid == info->fsid &&
iter->info.number == info->number &&
iter->info.owner == info->owner &&
iter->info.pid == info->pid &&
iter->info.start == info->start &&
iter->info.end == info->end &&
iter->info.ex == info->ex &&
iter->info.wait) {
op = iter;
break;
}
}
return op;
}
static int check_version(struct dlm_plock_info *info) static int check_version(struct dlm_plock_info *info)
{ {
if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) || if ((DLM_PLOCK_VERSION_MAJOR != info->version[0]) ||
...@@ -74,30 +97,26 @@ static void send_op(struct plock_op *op) ...@@ -74,30 +97,26 @@ static void send_op(struct plock_op *op)
wake_up(&send_wq); wake_up(&send_wq);
} }
/* If a process was killed while waiting for the only plock on a file, static int do_lock_cancel(const struct dlm_plock_info *orig_info)
locks_remove_posix will not see any lock on the file so it won't
send an unlock-close to us to pass on to userspace to clean up the
abandoned waiter. So, we have to insert the unlock-close when the
lock call is interrupted. */
static void do_unlock_close(const struct dlm_plock_info *info)
{ {
struct plock_op *op; struct plock_op *op;
int rv;
op = kzalloc(sizeof(*op), GFP_NOFS); op = kzalloc(sizeof(*op), GFP_NOFS);
if (!op) if (!op)
return; return -ENOMEM;
op->info = *orig_info;
op->info.optype = DLM_PLOCK_OP_CANCEL;
op->info.wait = 0;
op->info.optype = DLM_PLOCK_OP_UNLOCK;
op->info.pid = info->pid;
op->info.fsid = info->fsid;
op->info.number = info->number;
op->info.start = 0;
op->info.end = OFFSET_MAX;
op->info.owner = info->owner;
op->info.flags |= DLM_PLOCK_FL_CLOSE;
send_op(op); send_op(op);
wait_event(recv_wq, (op->done != 0));
rv = op->info.rv;
dlm_release_plock_op(op);
return rv;
} }
int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
...@@ -156,7 +175,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -156,7 +175,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
send_op(op); send_op(op);
if (op->info.wait) { if (op->info.wait) {
rv = wait_event_killable(recv_wq, (op->done != 0)); rv = wait_event_interruptible(recv_wq, (op->done != 0));
if (rv == -ERESTARTSYS) { if (rv == -ERESTARTSYS) {
spin_lock(&ops_lock); spin_lock(&ops_lock);
/* recheck under ops_lock if we got a done != 0, /* recheck under ops_lock if we got a done != 0,
...@@ -166,17 +185,37 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -166,17 +185,37 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
goto do_lock_wait; goto do_lock_wait;
} }
list_del(&op->list);
spin_unlock(&ops_lock); spin_unlock(&ops_lock);
rv = do_lock_cancel(&op->info);
switch (rv) {
case 0:
/* waiter was deleted in user space, answer will never come
* remove original request. The original request must be
* on recv_list because the answer of do_lock_cancel()
* synchronized it.
*/
spin_lock(&ops_lock);
list_del(&op->list);
spin_unlock(&ops_lock);
rv = -EINTR;
break;
case -ENOENT:
/* cancellation wasn't successful but op should be done */
fallthrough;
default:
/* internal error doing cancel we need to wait */
goto wait;
}
log_debug(ls, "%s: wait interrupted %x %llx pid %d", log_debug(ls, "%s: wait interrupted %x %llx pid %d",
__func__, ls->ls_global_id, __func__, ls->ls_global_id,
(unsigned long long)number, op->info.pid); (unsigned long long)number, op->info.pid);
do_unlock_close(&op->info);
dlm_release_plock_op(op); dlm_release_plock_op(op);
goto out; goto out;
} }
} else { } else {
wait:
wait_event(recv_wq, (op->done != 0)); wait_event(recv_wq, (op->done != 0));
} }
...@@ -240,8 +279,8 @@ static int dlm_plock_callback(struct plock_op *op) ...@@ -240,8 +279,8 @@ static int dlm_plock_callback(struct plock_op *op)
rv = notify(fl, 0); rv = notify(fl, 0);
if (rv) { if (rv) {
/* XXX: We need to cancel the fs lock here: */ /* XXX: We need to cancel the fs lock here: */
log_print("dlm_plock_callback: lock granted after lock request " log_print("%s: lock granted after lock request failed; dangling lock!",
"failed; dangling lock!\n"); __func__);
goto out; goto out;
} }
...@@ -318,6 +357,75 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -318,6 +357,75 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
} }
EXPORT_SYMBOL_GPL(dlm_posix_unlock); EXPORT_SYMBOL_GPL(dlm_posix_unlock);
/*
* NOTE: This implementation can only handle async lock requests as nfs
* do it. It cannot handle cancellation of a pending lock request sitting
* in wait_event(), but for now only nfs is the only user local kernel
* user.
*/
int dlm_posix_cancel(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl)
{
struct dlm_plock_info info;
struct plock_op *op;
struct dlm_ls *ls;
int rv;
/* this only works for async request for now and nfs is the only
* kernel user right now.
*/
if (WARN_ON_ONCE(!fl->fl_lmops || !fl->fl_lmops->lm_grant))
return -EOPNOTSUPP;
ls = dlm_find_lockspace_local(lockspace);
if (!ls)
return -EINVAL;
memset(&info, 0, sizeof(info));
info.pid = fl->fl_pid;
info.ex = (fl->fl_type == F_WRLCK);
info.fsid = ls->ls_global_id;
dlm_put_lockspace(ls);
info.number = number;
info.start = fl->fl_start;
info.end = fl->fl_end;
info.owner = (__u64)fl->fl_pid;
rv = do_lock_cancel(&info);
switch (rv) {
case 0:
spin_lock(&ops_lock);
/* lock request to cancel must be on recv_list because
* do_lock_cancel() synchronizes it.
*/
op = plock_lookup_waiter(&info);
if (WARN_ON_ONCE(!op)) {
spin_unlock(&ops_lock);
rv = -ENOLCK;
break;
}
list_del(&op->list);
spin_unlock(&ops_lock);
WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
op->data->callback(op->data->fl, -EINTR);
dlm_release_plock_op(op);
rv = -EINTR;
break;
case -ENOENT:
/* if cancel wasn't successful we probably were to late
* or it was a non-blocking lock request, so just unlock it.
*/
rv = dlm_posix_unlock(lockspace, number, file, fl);
break;
default:
break;
}
return rv;
}
EXPORT_SYMBOL_GPL(dlm_posix_cancel);
int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl) struct file_lock *fl)
{ {
...@@ -403,6 +511,8 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count, ...@@ -403,6 +511,8 @@ static ssize_t dev_read(struct file *file, char __user *u, size_t count,
if (!op) if (!op)
return -EAGAIN; return -EAGAIN;
trace_dlm_plock_read(&info);
/* there is no need to get a reply from userspace for unlocks /* there is no need to get a reply from userspace for unlocks
that were generated by the vfs cleaning up for a close that were generated by the vfs cleaning up for a close
(the process did not make an unlock call). */ (the process did not make an unlock call). */
...@@ -430,6 +540,8 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, ...@@ -430,6 +540,8 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
if (copy_from_user(&info, u, sizeof(info))) if (copy_from_user(&info, u, sizeof(info)))
return -EFAULT; return -EFAULT;
trace_dlm_plock_write(&info);
if (check_version(&info)) if (check_version(&info))
return -EINVAL; return -EINVAL;
...@@ -441,22 +553,11 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, ...@@ -441,22 +553,11 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
*/ */
spin_lock(&ops_lock); spin_lock(&ops_lock);
if (info.wait) { if (info.wait) {
list_for_each_entry(iter, &recv_list, list) { op = plock_lookup_waiter(&info);
if (iter->info.fsid == info.fsid &&
iter->info.number == info.number &&
iter->info.owner == info.owner &&
iter->info.pid == info.pid &&
iter->info.start == info.start &&
iter->info.end == info.end &&
iter->info.ex == info.ex &&
iter->info.wait) {
op = iter;
break;
}
}
} else { } else {
list_for_each_entry(iter, &recv_list, list) { list_for_each_entry(iter, &recv_list, list) {
if (!iter->info.wait) { if (!iter->info.wait &&
iter->info.fsid == info.fsid) {
op = iter; op = iter;
break; break;
} }
...@@ -468,8 +569,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, ...@@ -468,8 +569,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
if (info.wait) if (info.wait)
WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
else else
WARN_ON(op->info.fsid != info.fsid || WARN_ON(op->info.number != info.number ||
op->info.number != info.number ||
op->info.owner != info.owner || op->info.owner != info.owner ||
op->info.optype != info.optype); op->info.optype != info.optype);
...@@ -534,5 +634,7 @@ int dlm_plock_init(void) ...@@ -534,5 +634,7 @@ int dlm_plock_init(void)
void dlm_plock_exit(void) void dlm_plock_exit(void)
{ {
misc_deregister(&plock_dev_misc); misc_deregister(&plock_dev_misc);
WARN_ON(!list_empty(&send_list));
WARN_ON(!list_empty(&recv_list));
} }
This diff is collapsed.
...@@ -12,12 +12,15 @@ ...@@ -12,12 +12,15 @@
#ifndef __RCOM_DOT_H__ #ifndef __RCOM_DOT_H__
#define __RCOM_DOT_H__ #define __RCOM_DOT_H__
int dlm_rcom_status(struct dlm_ls *ls, int nodeid, uint32_t status_flags); int dlm_rcom_status(struct dlm_ls *ls, int nodeid, uint32_t status_flags,
int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name,int last_len); uint64_t seq);
int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid); int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name,
int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb); int last_len, uint64_t seq);
void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid); int dlm_send_rcom_lookup(struct dlm_rsb *r, int dir_nodeid, uint64_t seq);
int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in); int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb, uint64_t seq);
void dlm_receive_rcom(struct dlm_ls *ls, const struct dlm_rcom *rc,
int nodeid);
int dlm_send_ls_not_ready(int nodeid, const struct dlm_rcom *rc_in);
#endif #endif
...@@ -93,7 +93,7 @@ void dlm_set_recover_status(struct dlm_ls *ls, uint32_t status) ...@@ -93,7 +93,7 @@ void dlm_set_recover_status(struct dlm_ls *ls, uint32_t status)
} }
static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status, static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status,
int save_slots) int save_slots, uint64_t seq)
{ {
struct dlm_rcom *rc = ls->ls_recover_buf; struct dlm_rcom *rc = ls->ls_recover_buf;
struct dlm_member *memb; struct dlm_member *memb;
...@@ -107,7 +107,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status, ...@@ -107,7 +107,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status,
goto out; goto out;
} }
error = dlm_rcom_status(ls, memb->nodeid, 0); error = dlm_rcom_status(ls, memb->nodeid, 0, seq);
if (error) if (error)
goto out; goto out;
...@@ -126,7 +126,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status, ...@@ -126,7 +126,7 @@ static int wait_status_all(struct dlm_ls *ls, uint32_t wait_status,
} }
static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status, static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status,
uint32_t status_flags) uint32_t status_flags, uint64_t seq)
{ {
struct dlm_rcom *rc = ls->ls_recover_buf; struct dlm_rcom *rc = ls->ls_recover_buf;
int error = 0, delay = 0, nodeid = ls->ls_low_nodeid; int error = 0, delay = 0, nodeid = ls->ls_low_nodeid;
...@@ -137,7 +137,7 @@ static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status, ...@@ -137,7 +137,7 @@ static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status,
goto out; goto out;
} }
error = dlm_rcom_status(ls, nodeid, status_flags); error = dlm_rcom_status(ls, nodeid, status_flags, seq);
if (error) if (error)
break; break;
...@@ -151,22 +151,22 @@ static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status, ...@@ -151,22 +151,22 @@ static int wait_status_low(struct dlm_ls *ls, uint32_t wait_status,
return error; return error;
} }
static int wait_status(struct dlm_ls *ls, uint32_t status) static int wait_status(struct dlm_ls *ls, uint32_t status, uint64_t seq)
{ {
uint32_t status_all = status << 1; uint32_t status_all = status << 1;
int error; int error;
if (ls->ls_low_nodeid == dlm_our_nodeid()) { if (ls->ls_low_nodeid == dlm_our_nodeid()) {
error = wait_status_all(ls, status, 0); error = wait_status_all(ls, status, 0, seq);
if (!error) if (!error)
dlm_set_recover_status(ls, status_all); dlm_set_recover_status(ls, status_all);
} else } else
error = wait_status_low(ls, status_all, 0); error = wait_status_low(ls, status_all, 0, seq);
return error; return error;
} }
int dlm_recover_members_wait(struct dlm_ls *ls) int dlm_recover_members_wait(struct dlm_ls *ls, uint64_t seq)
{ {
struct dlm_member *memb; struct dlm_member *memb;
struct dlm_slot *slots; struct dlm_slot *slots;
...@@ -180,7 +180,7 @@ int dlm_recover_members_wait(struct dlm_ls *ls) ...@@ -180,7 +180,7 @@ int dlm_recover_members_wait(struct dlm_ls *ls)
} }
if (ls->ls_low_nodeid == dlm_our_nodeid()) { if (ls->ls_low_nodeid == dlm_our_nodeid()) {
error = wait_status_all(ls, DLM_RS_NODES, 1); error = wait_status_all(ls, DLM_RS_NODES, 1, seq);
if (error) if (error)
goto out; goto out;
...@@ -199,7 +199,8 @@ int dlm_recover_members_wait(struct dlm_ls *ls) ...@@ -199,7 +199,8 @@ int dlm_recover_members_wait(struct dlm_ls *ls)
dlm_set_recover_status(ls, DLM_RS_NODES_ALL); dlm_set_recover_status(ls, DLM_RS_NODES_ALL);
} }
} else { } else {
error = wait_status_low(ls, DLM_RS_NODES_ALL, DLM_RSF_NEED_SLOTS); error = wait_status_low(ls, DLM_RS_NODES_ALL,
DLM_RSF_NEED_SLOTS, seq);
if (error) if (error)
goto out; goto out;
...@@ -209,19 +210,19 @@ int dlm_recover_members_wait(struct dlm_ls *ls) ...@@ -209,19 +210,19 @@ int dlm_recover_members_wait(struct dlm_ls *ls)
return error; return error;
} }
int dlm_recover_directory_wait(struct dlm_ls *ls) int dlm_recover_directory_wait(struct dlm_ls *ls, uint64_t seq)
{ {
return wait_status(ls, DLM_RS_DIR); return wait_status(ls, DLM_RS_DIR, seq);
} }
int dlm_recover_locks_wait(struct dlm_ls *ls) int dlm_recover_locks_wait(struct dlm_ls *ls, uint64_t seq)
{ {
return wait_status(ls, DLM_RS_LOCKS); return wait_status(ls, DLM_RS_LOCKS, seq);
} }
int dlm_recover_done_wait(struct dlm_ls *ls) int dlm_recover_done_wait(struct dlm_ls *ls, uint64_t seq)
{ {
return wait_status(ls, DLM_RS_DONE); return wait_status(ls, DLM_RS_DONE, seq);
} }
/* /*
...@@ -441,7 +442,7 @@ static void set_new_master(struct dlm_rsb *r) ...@@ -441,7 +442,7 @@ static void set_new_master(struct dlm_rsb *r)
* equals our_nodeid below). * equals our_nodeid below).
*/ */
static int recover_master(struct dlm_rsb *r, unsigned int *count) static int recover_master(struct dlm_rsb *r, unsigned int *count, uint64_t seq)
{ {
struct dlm_ls *ls = r->res_ls; struct dlm_ls *ls = r->res_ls;
int our_nodeid, dir_nodeid; int our_nodeid, dir_nodeid;
...@@ -472,7 +473,7 @@ static int recover_master(struct dlm_rsb *r, unsigned int *count) ...@@ -472,7 +473,7 @@ static int recover_master(struct dlm_rsb *r, unsigned int *count)
error = 0; error = 0;
} else { } else {
recover_idr_add(r); recover_idr_add(r);
error = dlm_send_rcom_lookup(r, dir_nodeid); error = dlm_send_rcom_lookup(r, dir_nodeid, seq);
} }
(*count)++; (*count)++;
...@@ -520,7 +521,7 @@ static int recover_master_static(struct dlm_rsb *r, unsigned int *count) ...@@ -520,7 +521,7 @@ static int recover_master_static(struct dlm_rsb *r, unsigned int *count)
* the correct dir node. * the correct dir node.
*/ */
int dlm_recover_masters(struct dlm_ls *ls) int dlm_recover_masters(struct dlm_ls *ls, uint64_t seq)
{ {
struct dlm_rsb *r; struct dlm_rsb *r;
unsigned int total = 0; unsigned int total = 0;
...@@ -542,7 +543,7 @@ int dlm_recover_masters(struct dlm_ls *ls) ...@@ -542,7 +543,7 @@ int dlm_recover_masters(struct dlm_ls *ls)
if (nodir) if (nodir)
error = recover_master_static(r, &count); error = recover_master_static(r, &count);
else else
error = recover_master(r, &count); error = recover_master(r, &count, seq);
unlock_rsb(r); unlock_rsb(r);
cond_resched(); cond_resched();
total++; total++;
...@@ -563,7 +564,7 @@ int dlm_recover_masters(struct dlm_ls *ls) ...@@ -563,7 +564,7 @@ int dlm_recover_masters(struct dlm_ls *ls)
return error; return error;
} }
int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc) int dlm_recover_master_reply(struct dlm_ls *ls, const struct dlm_rcom *rc)
{ {
struct dlm_rsb *r; struct dlm_rsb *r;
int ret_nodeid, new_master; int ret_nodeid, new_master;
...@@ -614,13 +615,14 @@ int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc) ...@@ -614,13 +615,14 @@ int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
* an equal number of replies then recovery for the rsb is done * an equal number of replies then recovery for the rsb is done
*/ */
static int recover_locks_queue(struct dlm_rsb *r, struct list_head *head) static int recover_locks_queue(struct dlm_rsb *r, struct list_head *head,
uint64_t seq)
{ {
struct dlm_lkb *lkb; struct dlm_lkb *lkb;
int error = 0; int error = 0;
list_for_each_entry(lkb, head, lkb_statequeue) { list_for_each_entry(lkb, head, lkb_statequeue) {
error = dlm_send_rcom_lock(r, lkb); error = dlm_send_rcom_lock(r, lkb, seq);
if (error) if (error)
break; break;
r->res_recover_locks_count++; r->res_recover_locks_count++;
...@@ -629,7 +631,7 @@ static int recover_locks_queue(struct dlm_rsb *r, struct list_head *head) ...@@ -629,7 +631,7 @@ static int recover_locks_queue(struct dlm_rsb *r, struct list_head *head)
return error; return error;
} }
static int recover_locks(struct dlm_rsb *r) static int recover_locks(struct dlm_rsb *r, uint64_t seq)
{ {
int error = 0; int error = 0;
...@@ -637,13 +639,13 @@ static int recover_locks(struct dlm_rsb *r) ...@@ -637,13 +639,13 @@ static int recover_locks(struct dlm_rsb *r)
DLM_ASSERT(!r->res_recover_locks_count, dlm_dump_rsb(r);); DLM_ASSERT(!r->res_recover_locks_count, dlm_dump_rsb(r););
error = recover_locks_queue(r, &r->res_grantqueue); error = recover_locks_queue(r, &r->res_grantqueue, seq);
if (error) if (error)
goto out; goto out;
error = recover_locks_queue(r, &r->res_convertqueue); error = recover_locks_queue(r, &r->res_convertqueue, seq);
if (error) if (error)
goto out; goto out;
error = recover_locks_queue(r, &r->res_waitqueue); error = recover_locks_queue(r, &r->res_waitqueue, seq);
if (error) if (error)
goto out; goto out;
...@@ -656,7 +658,7 @@ static int recover_locks(struct dlm_rsb *r) ...@@ -656,7 +658,7 @@ static int recover_locks(struct dlm_rsb *r)
return error; return error;
} }
int dlm_recover_locks(struct dlm_ls *ls) int dlm_recover_locks(struct dlm_ls *ls, uint64_t seq)
{ {
struct dlm_rsb *r; struct dlm_rsb *r;
int error, count = 0; int error, count = 0;
...@@ -677,7 +679,7 @@ int dlm_recover_locks(struct dlm_ls *ls) ...@@ -677,7 +679,7 @@ int dlm_recover_locks(struct dlm_ls *ls)
goto out; goto out;
} }
error = recover_locks(r); error = recover_locks(r, seq);
if (error) { if (error) {
up_read(&ls->ls_root_sem); up_read(&ls->ls_root_sem);
goto out; goto out;
......
...@@ -15,13 +15,13 @@ ...@@ -15,13 +15,13 @@
int dlm_wait_function(struct dlm_ls *ls, int (*testfn) (struct dlm_ls *ls)); int dlm_wait_function(struct dlm_ls *ls, int (*testfn) (struct dlm_ls *ls));
uint32_t dlm_recover_status(struct dlm_ls *ls); uint32_t dlm_recover_status(struct dlm_ls *ls);
void dlm_set_recover_status(struct dlm_ls *ls, uint32_t status); void dlm_set_recover_status(struct dlm_ls *ls, uint32_t status);
int dlm_recover_members_wait(struct dlm_ls *ls); int dlm_recover_members_wait(struct dlm_ls *ls, uint64_t seq);
int dlm_recover_directory_wait(struct dlm_ls *ls); int dlm_recover_directory_wait(struct dlm_ls *ls, uint64_t seq);
int dlm_recover_locks_wait(struct dlm_ls *ls); int dlm_recover_locks_wait(struct dlm_ls *ls, uint64_t seq);
int dlm_recover_done_wait(struct dlm_ls *ls); int dlm_recover_done_wait(struct dlm_ls *ls, uint64_t seq);
int dlm_recover_masters(struct dlm_ls *ls); int dlm_recover_masters(struct dlm_ls *ls, uint64_t seq);
int dlm_recover_master_reply(struct dlm_ls *ls, struct dlm_rcom *rc); int dlm_recover_master_reply(struct dlm_ls *ls, const struct dlm_rcom *rc);
int dlm_recover_locks(struct dlm_ls *ls); int dlm_recover_locks(struct dlm_ls *ls, uint64_t seq);
void dlm_recovered_lock(struct dlm_rsb *r); void dlm_recovered_lock(struct dlm_rsb *r);
int dlm_create_root_list(struct dlm_ls *ls); int dlm_create_root_list(struct dlm_ls *ls);
void dlm_release_root_list(struct dlm_ls *ls); void dlm_release_root_list(struct dlm_ls *ls);
......
...@@ -90,7 +90,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -90,7 +90,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
dlm_set_recover_status(ls, DLM_RS_NODES); dlm_set_recover_status(ls, DLM_RS_NODES);
error = dlm_recover_members_wait(ls); error = dlm_recover_members_wait(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_members_wait error %d", error); log_rinfo(ls, "dlm_recover_members_wait error %d", error);
goto fail; goto fail;
...@@ -103,7 +103,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -103,7 +103,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
* nodes their master rsb names that hash to us. * nodes their master rsb names that hash to us.
*/ */
error = dlm_recover_directory(ls); error = dlm_recover_directory(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_directory error %d", error); log_rinfo(ls, "dlm_recover_directory error %d", error);
goto fail; goto fail;
...@@ -111,7 +111,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -111,7 +111,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
dlm_set_recover_status(ls, DLM_RS_DIR); dlm_set_recover_status(ls, DLM_RS_DIR);
error = dlm_recover_directory_wait(ls); error = dlm_recover_directory_wait(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_directory_wait error %d", error); log_rinfo(ls, "dlm_recover_directory_wait error %d", error);
goto fail; goto fail;
...@@ -145,7 +145,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -145,7 +145,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
* departed nodes. * departed nodes.
*/ */
error = dlm_recover_masters(ls); error = dlm_recover_masters(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_masters error %d", error); log_rinfo(ls, "dlm_recover_masters error %d", error);
goto fail; goto fail;
...@@ -155,7 +155,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -155,7 +155,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
* Send our locks on remastered rsb's to the new masters. * Send our locks on remastered rsb's to the new masters.
*/ */
error = dlm_recover_locks(ls); error = dlm_recover_locks(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_locks error %d", error); log_rinfo(ls, "dlm_recover_locks error %d", error);
goto fail; goto fail;
...@@ -163,7 +163,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -163,7 +163,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
dlm_set_recover_status(ls, DLM_RS_LOCKS); dlm_set_recover_status(ls, DLM_RS_LOCKS);
error = dlm_recover_locks_wait(ls); error = dlm_recover_locks_wait(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_locks_wait error %d", error); log_rinfo(ls, "dlm_recover_locks_wait error %d", error);
goto fail; goto fail;
...@@ -187,7 +187,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -187,7 +187,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
*/ */
dlm_set_recover_status(ls, DLM_RS_LOCKS); dlm_set_recover_status(ls, DLM_RS_LOCKS);
error = dlm_recover_locks_wait(ls); error = dlm_recover_locks_wait(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_locks_wait error %d", error); log_rinfo(ls, "dlm_recover_locks_wait error %d", error);
goto fail; goto fail;
...@@ -206,7 +206,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) ...@@ -206,7 +206,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv)
dlm_set_recover_status(ls, DLM_RS_DONE); dlm_set_recover_status(ls, DLM_RS_DONE);
error = dlm_recover_done_wait(ls); error = dlm_recover_done_wait(ls, rv->seq);
if (error) { if (error) {
log_rinfo(ls, "dlm_recover_done_wait error %d", error); log_rinfo(ls, "dlm_recover_done_wait error %d", error);
goto fail; goto fail;
......
...@@ -30,7 +30,8 @@ struct rq_entry { ...@@ -30,7 +30,8 @@ struct rq_entry {
* lockspace is enabled on some while still suspended on others. * lockspace is enabled on some while still suspended on others.
*/ */
void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms) void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid,
const struct dlm_message *ms)
{ {
struct rq_entry *e; struct rq_entry *e;
int length = le16_to_cpu(ms->m_header.h_length) - int length = le16_to_cpu(ms->m_header.h_length) -
......
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#ifndef __REQUESTQUEUE_DOT_H__ #ifndef __REQUESTQUEUE_DOT_H__
#define __REQUESTQUEUE_DOT_H__ #define __REQUESTQUEUE_DOT_H__
void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms); void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid,
const struct dlm_message *ms);
int dlm_process_requestqueue(struct dlm_ls *ls); int dlm_process_requestqueue(struct dlm_ls *ls);
void dlm_wait_requestqueue(struct dlm_ls *ls); void dlm_wait_requestqueue(struct dlm_ls *ls);
void dlm_purge_requestqueue(struct dlm_ls *ls); void dlm_purge_requestqueue(struct dlm_ls *ls);
......
...@@ -1436,17 +1436,14 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) ...@@ -1436,17 +1436,14 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_POSIX)) if (!(fl->fl_flags & FL_POSIX))
return -ENOLCK; return -ENOLCK;
if (cmd == F_CANCELLK) {
/* Hack: */
cmd = F_SETLK;
fl->fl_type = F_UNLCK;
}
if (unlikely(gfs2_withdrawn(sdp))) { if (unlikely(gfs2_withdrawn(sdp))) {
if (fl->fl_type == F_UNLCK) if (fl->fl_type == F_UNLCK)
locks_lock_file_wait(file, fl); locks_lock_file_wait(file, fl);
return -EIO; return -EIO;
} }
if (IS_GETLK(cmd)) if (cmd == F_CANCELLK)
return dlm_posix_cancel(ls->ls_dlm, ip->i_no_addr, file, fl);
else if (IS_GETLK(cmd))
return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl);
else if (fl->fl_type == F_UNLCK) else if (fl->fl_type == F_UNLCK)
return dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl); return dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl);
......
...@@ -738,18 +738,11 @@ static int user_plock(struct ocfs2_cluster_connection *conn, ...@@ -738,18 +738,11 @@ static int user_plock(struct ocfs2_cluster_connection *conn,
* *
* Internally, fs/dlm will pass these to a misc device, which * Internally, fs/dlm will pass these to a misc device, which
* a userspace daemon will read and write to. * a userspace daemon will read and write to.
*
* For now, cancel requests (which happen internally only),
* are turned into unlocks. Most of this function taken from
* gfs2_lock.
*/ */
if (cmd == F_CANCELLK) { if (cmd == F_CANCELLK)
cmd = F_SETLK; return dlm_posix_cancel(conn->cc_lockspace, ino, file, fl);
fl->fl_type = F_UNLCK; else if (IS_GETLK(cmd))
}
if (IS_GETLK(cmd))
return dlm_posix_get(conn->cc_lockspace, ino, file, fl); return dlm_posix_get(conn->cc_lockspace, ino, file, fl);
else if (fl->fl_type == F_UNLCK) else if (fl->fl_type == F_UNLCK)
return dlm_posix_unlock(conn->cc_lockspace, ino, file, fl); return dlm_posix_unlock(conn->cc_lockspace, ino, file, fl);
......
...@@ -11,6 +11,8 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, ...@@ -11,6 +11,8 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
int cmd, struct file_lock *fl); int cmd, struct file_lock *fl);
int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl); struct file_lock *fl);
int dlm_posix_cancel(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, int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file,
struct file_lock *fl); struct file_lock *fl);
#endif #endif
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/dlm.h> #include <linux/dlm.h>
#include <linux/dlmconstants.h> #include <linux/dlmconstants.h>
#include <uapi/linux/dlm_plock.h>
#include <linux/tracepoint.h> #include <linux/tracepoint.h>
#include "../../../fs/dlm/dlm_internal.h" #include "../../../fs/dlm/dlm_internal.h"
...@@ -585,6 +586,56 @@ TRACE_EVENT(dlm_recv_message, ...@@ -585,6 +586,56 @@ TRACE_EVENT(dlm_recv_message,
); );
DECLARE_EVENT_CLASS(dlm_plock_template,
TP_PROTO(const struct dlm_plock_info *info),
TP_ARGS(info),
TP_STRUCT__entry(
__field(uint8_t, optype)
__field(uint8_t, ex)
__field(uint8_t, wait)
__field(uint8_t, flags)
__field(uint32_t, pid)
__field(int32_t, nodeid)
__field(int32_t, rv)
__field(uint32_t, fsid)
__field(uint64_t, number)
__field(uint64_t, start)
__field(uint64_t, end)
__field(uint64_t, owner)
),
TP_fast_assign(
__entry->optype = info->optype;
__entry->ex = info->ex;
__entry->wait = info->wait;
__entry->flags = info->flags;
__entry->pid = info->pid;
__entry->nodeid = info->nodeid;
__entry->rv = info->rv;
__entry->fsid = info->fsid;
__entry->number = info->number;
__entry->start = info->start;
__entry->end = info->end;
__entry->owner = info->owner;
),
TP_printk("fsid=%u number=%llx owner=%llx optype=%d ex=%d wait=%d flags=%x pid=%u nodeid=%d rv=%d start=%llx end=%llx",
__entry->fsid, __entry->number, __entry->owner,
__entry->optype, __entry->ex, __entry->wait,
__entry->flags, __entry->pid, __entry->nodeid,
__entry->rv, __entry->start, __entry->end)
);
DEFINE_EVENT(dlm_plock_template, dlm_plock_read,
TP_PROTO(const struct dlm_plock_info *info), TP_ARGS(info));
DEFINE_EVENT(dlm_plock_template, dlm_plock_write,
TP_PROTO(const struct dlm_plock_info *info), TP_ARGS(info));
TRACE_EVENT(dlm_send, TRACE_EVENT(dlm_send,
TP_PROTO(int nodeid, int ret), TP_PROTO(int nodeid, int ret),
......
...@@ -22,6 +22,7 @@ enum { ...@@ -22,6 +22,7 @@ enum {
DLM_PLOCK_OP_LOCK = 1, DLM_PLOCK_OP_LOCK = 1,
DLM_PLOCK_OP_UNLOCK, DLM_PLOCK_OP_UNLOCK,
DLM_PLOCK_OP_GET, DLM_PLOCK_OP_GET,
DLM_PLOCK_OP_CANCEL,
}; };
#define DLM_PLOCK_FL_CLOSE 1 #define DLM_PLOCK_FL_CLOSE 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment