mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-15 04:47:32 +07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm: dlm: add __init and __exit marks to init and exit functions dlm: eliminate astparam type casting dlm: proper types for asts and basts dlm: dlm/user.c input validation fixes dlm: fix dlm_dir_lookup() handling of too long names dlm: fix overflows when copying from ->m_extra to lvb dlm: make find_rsb() fail gracefully when namelen is too large dlm: receive_rcom_lock_args() overflow check dlm: verify that places expecting rcom_lock have packet long enough dlm: validate data in dlm_recover_directory() dlm: missing length check in check_config() dlm: use proper type for ->ls_recover_buf dlm: do not byteswap rcom_config dlm: do not byteswap rcom_lock dlm: dlm_process_incoming_buffer() fixes dlm: use proper C for dlm/requestqueue stuff (and fix alignment bug)
This commit is contained in:
commit
b5eb9513f7
@ -39,7 +39,6 @@ void dlm_add_ast(struct dlm_lkb *lkb, int type)
|
|||||||
dlm_user_add_ast(lkb, type);
|
dlm_user_add_ast(lkb, type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DLM_ASSERT(lkb->lkb_astaddr != DLM_FAKE_USER_AST, dlm_print_lkb(lkb););
|
|
||||||
|
|
||||||
spin_lock(&ast_queue_lock);
|
spin_lock(&ast_queue_lock);
|
||||||
if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
|
if (!(lkb->lkb_ast_type & (AST_COMP | AST_BAST))) {
|
||||||
@ -58,8 +57,8 @@ static void process_asts(void)
|
|||||||
struct dlm_ls *ls = NULL;
|
struct dlm_ls *ls = NULL;
|
||||||
struct dlm_rsb *r = NULL;
|
struct dlm_rsb *r = NULL;
|
||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
void (*cast) (long param);
|
void (*cast) (void *astparam);
|
||||||
void (*bast) (long param, int mode);
|
void (*bast) (void *astparam, int mode);
|
||||||
int type = 0, found, bmode;
|
int type = 0, found, bmode;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -83,8 +82,8 @@ static void process_asts(void)
|
|||||||
if (!found)
|
if (!found)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
cast = lkb->lkb_astaddr;
|
cast = lkb->lkb_astfn;
|
||||||
bast = lkb->lkb_bastaddr;
|
bast = lkb->lkb_bastfn;
|
||||||
bmode = lkb->lkb_bastmode;
|
bmode = lkb->lkb_bastmode;
|
||||||
|
|
||||||
if ((type & AST_COMP) && cast)
|
if ((type & AST_COMP) && cast)
|
||||||
|
@ -604,7 +604,7 @@ static struct clusters clusters_root = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int dlm_config_init(void)
|
int __init dlm_config_init(void)
|
||||||
{
|
{
|
||||||
config_group_init(&clusters_root.subsys.su_group);
|
config_group_init(&clusters_root.subsys.su_group);
|
||||||
mutex_init(&clusters_root.subsys.su_mutex);
|
mutex_init(&clusters_root.subsys.su_mutex);
|
||||||
|
@ -162,14 +162,12 @@ static int print_resource(struct dlm_rsb *res, struct seq_file *s)
|
|||||||
|
|
||||||
static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r)
|
static void print_lock(struct seq_file *s, struct dlm_lkb *lkb, struct dlm_rsb *r)
|
||||||
{
|
{
|
||||||
struct dlm_user_args *ua;
|
|
||||||
unsigned int waiting = 0;
|
unsigned int waiting = 0;
|
||||||
uint64_t xid = 0;
|
uint64_t xid = 0;
|
||||||
|
|
||||||
if (lkb->lkb_flags & DLM_IFL_USER) {
|
if (lkb->lkb_flags & DLM_IFL_USER) {
|
||||||
ua = (struct dlm_user_args *) lkb->lkb_astparam;
|
if (lkb->lkb_ua)
|
||||||
if (ua)
|
xid = lkb->lkb_ua->xid;
|
||||||
xid = ua->xid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lkb->lkb_timestamp)
|
if (lkb->lkb_timestamp)
|
||||||
@ -543,7 +541,7 @@ void dlm_delete_debug_file(struct dlm_ls *ls)
|
|||||||
debugfs_remove(ls->ls_debug_locks_dentry);
|
debugfs_remove(ls->ls_debug_locks_dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
int dlm_register_debugfs(void)
|
int __init dlm_register_debugfs(void)
|
||||||
{
|
{
|
||||||
mutex_init(&debug_buf_lock);
|
mutex_init(&debug_buf_lock);
|
||||||
dlm_root = debugfs_create_dir("dlm", NULL);
|
dlm_root = debugfs_create_dir("dlm", NULL);
|
||||||
|
28
fs/dlm/dir.c
28
fs/dlm/dir.c
@ -220,6 +220,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
|
|||||||
last_len = 0;
|
last_len = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
int left;
|
||||||
error = dlm_recovery_stopped(ls);
|
error = dlm_recovery_stopped(ls);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
@ -235,12 +236,21 @@ int dlm_recover_directory(struct dlm_ls *ls)
|
|||||||
* pick namelen/name pairs out of received buffer
|
* pick namelen/name pairs out of received buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
b = ls->ls_recover_buf + sizeof(struct dlm_rcom);
|
b = ls->ls_recover_buf->rc_buf;
|
||||||
|
left = ls->ls_recover_buf->rc_header.h_length;
|
||||||
|
left -= sizeof(struct dlm_rcom);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
memcpy(&namelen, b, sizeof(uint16_t));
|
__be16 v;
|
||||||
namelen = be16_to_cpu(namelen);
|
|
||||||
b += sizeof(uint16_t);
|
error = -EINVAL;
|
||||||
|
if (left < sizeof(__be16))
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
|
memcpy(&v, b, sizeof(__be16));
|
||||||
|
namelen = be16_to_cpu(v);
|
||||||
|
b += sizeof(__be16);
|
||||||
|
left -= sizeof(__be16);
|
||||||
|
|
||||||
/* namelen of 0xFFFFF marks end of names for
|
/* namelen of 0xFFFFF marks end of names for
|
||||||
this node; namelen of 0 marks end of the
|
this node; namelen of 0 marks end of the
|
||||||
@ -251,6 +261,12 @@ int dlm_recover_directory(struct dlm_ls *ls)
|
|||||||
if (!namelen)
|
if (!namelen)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (namelen > left)
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
|
if (namelen > DLM_RESNAME_MAXLEN)
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
de = get_free_de(ls, namelen);
|
de = get_free_de(ls, namelen);
|
||||||
if (!de)
|
if (!de)
|
||||||
@ -262,6 +278,7 @@ int dlm_recover_directory(struct dlm_ls *ls)
|
|||||||
memcpy(de->name, b, namelen);
|
memcpy(de->name, b, namelen);
|
||||||
memcpy(last_name, b, namelen);
|
memcpy(last_name, b, namelen);
|
||||||
b += namelen;
|
b += namelen;
|
||||||
|
left -= namelen;
|
||||||
|
|
||||||
add_entry_to_hash(ls, de);
|
add_entry_to_hash(ls, de);
|
||||||
count++;
|
count++;
|
||||||
@ -302,6 +319,9 @@ static int get_entry(struct dlm_ls *ls, int nodeid, char *name,
|
|||||||
|
|
||||||
write_unlock(&ls->ls_dirtbl[bucket].lock);
|
write_unlock(&ls->ls_dirtbl[bucket].lock);
|
||||||
|
|
||||||
|
if (namelen > DLM_RESNAME_MAXLEN)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
|
de = kzalloc(sizeof(struct dlm_direntry) + namelen, GFP_KERNEL);
|
||||||
if (!de)
|
if (!de)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -92,8 +92,6 @@ do { \
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DLM_FAKE_USER_AST ERR_PTR(-EINVAL)
|
|
||||||
|
|
||||||
|
|
||||||
struct dlm_direntry {
|
struct dlm_direntry {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
@ -146,9 +144,9 @@ struct dlm_recover {
|
|||||||
|
|
||||||
struct dlm_args {
|
struct dlm_args {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
void *astaddr;
|
void (*astfn) (void *astparam);
|
||||||
long astparam;
|
void *astparam;
|
||||||
void *bastaddr;
|
void (*bastfn) (void *astparam, int mode);
|
||||||
int mode;
|
int mode;
|
||||||
struct dlm_lksb *lksb;
|
struct dlm_lksb *lksb;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
@ -253,9 +251,12 @@ struct dlm_lkb {
|
|||||||
|
|
||||||
char *lkb_lvbptr;
|
char *lkb_lvbptr;
|
||||||
struct dlm_lksb *lkb_lksb; /* caller's status block */
|
struct dlm_lksb *lkb_lksb; /* caller's status block */
|
||||||
void *lkb_astaddr; /* caller's ast function */
|
void (*lkb_astfn) (void *astparam);
|
||||||
void *lkb_bastaddr; /* caller's bast function */
|
void (*lkb_bastfn) (void *astparam, int mode);
|
||||||
long lkb_astparam; /* caller's ast arg */
|
union {
|
||||||
|
void *lkb_astparam; /* caller's ast arg */
|
||||||
|
struct dlm_user_args *lkb_ua;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -403,28 +404,34 @@ struct dlm_rcom {
|
|||||||
char rc_buf[0];
|
char rc_buf[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union dlm_packet {
|
||||||
|
struct dlm_header header; /* common to other two */
|
||||||
|
struct dlm_message message;
|
||||||
|
struct dlm_rcom rcom;
|
||||||
|
};
|
||||||
|
|
||||||
struct rcom_config {
|
struct rcom_config {
|
||||||
uint32_t rf_lvblen;
|
__le32 rf_lvblen;
|
||||||
uint32_t rf_lsflags;
|
__le32 rf_lsflags;
|
||||||
uint64_t rf_unused;
|
__le64 rf_unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rcom_lock {
|
struct rcom_lock {
|
||||||
uint32_t rl_ownpid;
|
__le32 rl_ownpid;
|
||||||
uint32_t rl_lkid;
|
__le32 rl_lkid;
|
||||||
uint32_t rl_remid;
|
__le32 rl_remid;
|
||||||
uint32_t rl_parent_lkid;
|
__le32 rl_parent_lkid;
|
||||||
uint32_t rl_parent_remid;
|
__le32 rl_parent_remid;
|
||||||
uint32_t rl_exflags;
|
__le32 rl_exflags;
|
||||||
uint32_t rl_flags;
|
__le32 rl_flags;
|
||||||
uint32_t rl_lvbseq;
|
__le32 rl_lvbseq;
|
||||||
int rl_result;
|
__le32 rl_result;
|
||||||
int8_t rl_rqmode;
|
int8_t rl_rqmode;
|
||||||
int8_t rl_grmode;
|
int8_t rl_grmode;
|
||||||
int8_t rl_status;
|
int8_t rl_status;
|
||||||
int8_t rl_asts;
|
int8_t rl_asts;
|
||||||
uint16_t rl_wait_type;
|
__le16 rl_wait_type;
|
||||||
uint16_t rl_namelen;
|
__le16 rl_namelen;
|
||||||
char rl_name[DLM_RESNAME_MAXLEN];
|
char rl_name[DLM_RESNAME_MAXLEN];
|
||||||
char rl_lvb[0];
|
char rl_lvb[0];
|
||||||
};
|
};
|
||||||
@ -494,7 +501,7 @@ struct dlm_ls {
|
|||||||
struct rw_semaphore ls_recv_active; /* block dlm_recv */
|
struct rw_semaphore ls_recv_active; /* block dlm_recv */
|
||||||
struct list_head ls_requestqueue;/* queue remote requests */
|
struct list_head ls_requestqueue;/* queue remote requests */
|
||||||
struct mutex ls_requestqueue_mutex;
|
struct mutex ls_requestqueue_mutex;
|
||||||
char *ls_recover_buf;
|
struct dlm_rcom *ls_recover_buf;
|
||||||
int ls_recover_nodeid; /* for debugging */
|
int ls_recover_nodeid; /* for debugging */
|
||||||
uint64_t ls_rcom_seq;
|
uint64_t ls_rcom_seq;
|
||||||
spinlock_t ls_rcom_spin;
|
spinlock_t ls_rcom_spin;
|
||||||
|
139
fs/dlm/lock.c
139
fs/dlm/lock.c
@ -436,11 +436,15 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
|
|||||||
{
|
{
|
||||||
struct dlm_rsb *r, *tmp;
|
struct dlm_rsb *r, *tmp;
|
||||||
uint32_t hash, bucket;
|
uint32_t hash, bucket;
|
||||||
int error = 0;
|
int error = -EINVAL;
|
||||||
|
|
||||||
|
if (namelen > DLM_RESNAME_MAXLEN)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (dlm_no_directory(ls))
|
if (dlm_no_directory(ls))
|
||||||
flags |= R_CREATE;
|
flags |= R_CREATE;
|
||||||
|
|
||||||
|
error = 0;
|
||||||
hash = jhash(name, namelen, 0);
|
hash = jhash(name, namelen, 0);
|
||||||
bucket = hash & (ls->ls_rsbtbl_size - 1);
|
bucket = hash & (ls->ls_rsbtbl_size - 1);
|
||||||
|
|
||||||
@ -1222,6 +1226,8 @@ static void set_lvb_lock_pc(struct dlm_rsb *r, struct dlm_lkb *lkb,
|
|||||||
b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1];
|
b = dlm_lvb_operations[lkb->lkb_grmode + 1][lkb->lkb_rqmode + 1];
|
||||||
if (b == 1) {
|
if (b == 1) {
|
||||||
int len = receive_extralen(ms);
|
int len = receive_extralen(ms);
|
||||||
|
if (len > DLM_RESNAME_MAXLEN)
|
||||||
|
len = DLM_RESNAME_MAXLEN;
|
||||||
memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
|
memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
|
||||||
lkb->lkb_lvbseq = ms->m_lvbseq;
|
lkb->lkb_lvbseq = ms->m_lvbseq;
|
||||||
}
|
}
|
||||||
@ -1775,7 +1781,7 @@ static void grant_pending_locks(struct dlm_rsb *r)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
|
list_for_each_entry_safe(lkb, s, &r->res_grantqueue, lkb_statequeue) {
|
||||||
if (lkb->lkb_bastaddr && lock_requires_bast(lkb, high, cw)) {
|
if (lkb->lkb_bastfn && lock_requires_bast(lkb, high, cw)) {
|
||||||
if (cw && high == DLM_LOCK_PR)
|
if (cw && high == DLM_LOCK_PR)
|
||||||
queue_bast(r, lkb, DLM_LOCK_CW);
|
queue_bast(r, lkb, DLM_LOCK_CW);
|
||||||
else
|
else
|
||||||
@ -1805,7 +1811,7 @@ static void send_bast_queue(struct dlm_rsb *r, struct list_head *head,
|
|||||||
struct dlm_lkb *gr;
|
struct dlm_lkb *gr;
|
||||||
|
|
||||||
list_for_each_entry(gr, head, lkb_statequeue) {
|
list_for_each_entry(gr, head, lkb_statequeue) {
|
||||||
if (gr->lkb_bastaddr && modes_require_bast(gr, lkb)) {
|
if (gr->lkb_bastfn && modes_require_bast(gr, lkb)) {
|
||||||
queue_bast(r, gr, lkb->lkb_rqmode);
|
queue_bast(r, gr, lkb->lkb_rqmode);
|
||||||
gr->lkb_highbast = lkb->lkb_rqmode;
|
gr->lkb_highbast = lkb->lkb_rqmode;
|
||||||
}
|
}
|
||||||
@ -1960,8 +1966,11 @@ static void confirm_master(struct dlm_rsb *r, int error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
|
static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
|
||||||
int namelen, unsigned long timeout_cs, void *ast,
|
int namelen, unsigned long timeout_cs,
|
||||||
void *astarg, void *bast, struct dlm_args *args)
|
void (*ast) (void *astparam),
|
||||||
|
void *astparam,
|
||||||
|
void (*bast) (void *astparam, int mode),
|
||||||
|
struct dlm_args *args)
|
||||||
{
|
{
|
||||||
int rv = -EINVAL;
|
int rv = -EINVAL;
|
||||||
|
|
||||||
@ -2011,9 +2020,9 @@ static int set_lock_args(int mode, struct dlm_lksb *lksb, uint32_t flags,
|
|||||||
an active lkb cannot be modified before locking the rsb */
|
an active lkb cannot be modified before locking the rsb */
|
||||||
|
|
||||||
args->flags = flags;
|
args->flags = flags;
|
||||||
args->astaddr = ast;
|
args->astfn = ast;
|
||||||
args->astparam = (long) astarg;
|
args->astparam = astparam;
|
||||||
args->bastaddr = bast;
|
args->bastfn = bast;
|
||||||
args->timeout = timeout_cs;
|
args->timeout = timeout_cs;
|
||||||
args->mode = mode;
|
args->mode = mode;
|
||||||
args->lksb = lksb;
|
args->lksb = lksb;
|
||||||
@ -2032,7 +2041,7 @@ static int set_unlock_args(uint32_t flags, void *astarg, struct dlm_args *args)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
args->flags = flags;
|
args->flags = flags;
|
||||||
args->astparam = (long) astarg;
|
args->astparam = astarg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2062,9 +2071,9 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
|||||||
|
|
||||||
lkb->lkb_exflags = args->flags;
|
lkb->lkb_exflags = args->flags;
|
||||||
lkb->lkb_sbflags = 0;
|
lkb->lkb_sbflags = 0;
|
||||||
lkb->lkb_astaddr = args->astaddr;
|
lkb->lkb_astfn = args->astfn;
|
||||||
lkb->lkb_astparam = args->astparam;
|
lkb->lkb_astparam = args->astparam;
|
||||||
lkb->lkb_bastaddr = args->bastaddr;
|
lkb->lkb_bastfn = args->bastfn;
|
||||||
lkb->lkb_rqmode = args->mode;
|
lkb->lkb_rqmode = args->mode;
|
||||||
lkb->lkb_lksb = args->lksb;
|
lkb->lkb_lksb = args->lksb;
|
||||||
lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
|
lkb->lkb_lvbptr = args->lksb->sb_lvbptr;
|
||||||
@ -2711,9 +2720,9 @@ static void send_args(struct dlm_rsb *r, struct dlm_lkb *lkb,
|
|||||||
/* m_result and m_bastmode are set from function args,
|
/* m_result and m_bastmode are set from function args,
|
||||||
not from lkb fields */
|
not from lkb fields */
|
||||||
|
|
||||||
if (lkb->lkb_bastaddr)
|
if (lkb->lkb_bastfn)
|
||||||
ms->m_asts |= AST_BAST;
|
ms->m_asts |= AST_BAST;
|
||||||
if (lkb->lkb_astaddr)
|
if (lkb->lkb_astfn)
|
||||||
ms->m_asts |= AST_COMP;
|
ms->m_asts |= AST_COMP;
|
||||||
|
|
||||||
/* compare with switch in create_message; send_remove() doesn't
|
/* compare with switch in create_message; send_remove() doesn't
|
||||||
@ -2989,11 +2998,23 @@ static int receive_lvb(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
|||||||
if (!lkb->lkb_lvbptr)
|
if (!lkb->lkb_lvbptr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
len = receive_extralen(ms);
|
len = receive_extralen(ms);
|
||||||
|
if (len > DLM_RESNAME_MAXLEN)
|
||||||
|
len = DLM_RESNAME_MAXLEN;
|
||||||
memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
|
memcpy(lkb->lkb_lvbptr, ms->m_extra, len);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fake_bastfn(void *astparam, int mode)
|
||||||
|
{
|
||||||
|
log_print("fake_bastfn should not be called");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fake_astfn(void *astparam)
|
||||||
|
{
|
||||||
|
log_print("fake_astfn should not be called");
|
||||||
|
}
|
||||||
|
|
||||||
static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
||||||
struct dlm_message *ms)
|
struct dlm_message *ms)
|
||||||
{
|
{
|
||||||
@ -3002,8 +3023,9 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
|||||||
lkb->lkb_remid = ms->m_lkid;
|
lkb->lkb_remid = ms->m_lkid;
|
||||||
lkb->lkb_grmode = DLM_LOCK_IV;
|
lkb->lkb_grmode = DLM_LOCK_IV;
|
||||||
lkb->lkb_rqmode = ms->m_rqmode;
|
lkb->lkb_rqmode = ms->m_rqmode;
|
||||||
lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST);
|
|
||||||
lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP);
|
lkb->lkb_bastfn = (ms->m_asts & AST_BAST) ? &fake_bastfn : NULL;
|
||||||
|
lkb->lkb_astfn = (ms->m_asts & AST_COMP) ? &fake_astfn : NULL;
|
||||||
|
|
||||||
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
|
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
|
||||||
/* lkb was just created so there won't be an lvb yet */
|
/* lkb was just created so there won't be an lvb yet */
|
||||||
@ -3802,7 +3824,7 @@ static void dlm_receive_message(struct dlm_ls *ls, struct dlm_message *ms,
|
|||||||
int nodeid)
|
int nodeid)
|
||||||
{
|
{
|
||||||
if (dlm_locking_stopped(ls)) {
|
if (dlm_locking_stopped(ls)) {
|
||||||
dlm_add_requestqueue(ls, nodeid, (struct dlm_header *) ms);
|
dlm_add_requestqueue(ls, nodeid, ms);
|
||||||
} else {
|
} else {
|
||||||
dlm_wait_requestqueue(ls);
|
dlm_wait_requestqueue(ls);
|
||||||
_receive_message(ls, ms);
|
_receive_message(ls, ms);
|
||||||
@ -3822,21 +3844,20 @@ void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms)
|
|||||||
standard locking activity) or an RCOM (recovery message sent as part of
|
standard locking activity) or an RCOM (recovery message sent as part of
|
||||||
lockspace recovery). */
|
lockspace recovery). */
|
||||||
|
|
||||||
void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
|
void dlm_receive_buffer(union dlm_packet *p, int nodeid)
|
||||||
{
|
{
|
||||||
struct dlm_message *ms = (struct dlm_message *) hd;
|
struct dlm_header *hd = &p->header;
|
||||||
struct dlm_rcom *rc = (struct dlm_rcom *) hd;
|
|
||||||
struct dlm_ls *ls;
|
struct dlm_ls *ls;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
switch (hd->h_cmd) {
|
switch (hd->h_cmd) {
|
||||||
case DLM_MSG:
|
case DLM_MSG:
|
||||||
dlm_message_in(ms);
|
dlm_message_in(&p->message);
|
||||||
type = ms->m_type;
|
type = p->message.m_type;
|
||||||
break;
|
break;
|
||||||
case DLM_RCOM:
|
case DLM_RCOM:
|
||||||
dlm_rcom_in(rc);
|
dlm_rcom_in(&p->rcom);
|
||||||
type = rc->rc_type;
|
type = p->rcom.rc_type;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid);
|
log_print("invalid h_cmd %d from %u", hd->h_cmd, nodeid);
|
||||||
@ -3856,7 +3877,7 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
|
|||||||
hd->h_lockspace, nodeid, hd->h_cmd, type);
|
hd->h_lockspace, nodeid, hd->h_cmd, type);
|
||||||
|
|
||||||
if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
|
if (hd->h_cmd == DLM_RCOM && type == DLM_RCOM_STATUS)
|
||||||
dlm_send_ls_not_ready(nodeid, rc);
|
dlm_send_ls_not_ready(nodeid, &p->rcom);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3865,9 +3886,9 @@ void dlm_receive_buffer(struct dlm_header *hd, int nodeid)
|
|||||||
|
|
||||||
down_read(&ls->ls_recv_active);
|
down_read(&ls->ls_recv_active);
|
||||||
if (hd->h_cmd == DLM_MSG)
|
if (hd->h_cmd == DLM_MSG)
|
||||||
dlm_receive_message(ls, ms, nodeid);
|
dlm_receive_message(ls, &p->message, nodeid);
|
||||||
else
|
else
|
||||||
dlm_receive_rcom(ls, rc, nodeid);
|
dlm_receive_rcom(ls, &p->rcom, nodeid);
|
||||||
up_read(&ls->ls_recv_active);
|
up_read(&ls->ls_recv_active);
|
||||||
|
|
||||||
dlm_put_lockspace(ls);
|
dlm_put_lockspace(ls);
|
||||||
@ -4267,32 +4288,34 @@ static struct dlm_lkb *search_remid(struct dlm_rsb *r, int nodeid,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* needs at least dlm_rcom + rcom_lock */
|
||||||
static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
||||||
struct dlm_rsb *r, struct dlm_rcom *rc)
|
struct dlm_rsb *r, struct dlm_rcom *rc)
|
||||||
{
|
{
|
||||||
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
||||||
int lvblen;
|
|
||||||
|
|
||||||
lkb->lkb_nodeid = rc->rc_header.h_nodeid;
|
lkb->lkb_nodeid = rc->rc_header.h_nodeid;
|
||||||
lkb->lkb_ownpid = rl->rl_ownpid;
|
lkb->lkb_ownpid = le32_to_cpu(rl->rl_ownpid);
|
||||||
lkb->lkb_remid = rl->rl_lkid;
|
lkb->lkb_remid = le32_to_cpu(rl->rl_lkid);
|
||||||
lkb->lkb_exflags = rl->rl_exflags;
|
lkb->lkb_exflags = le32_to_cpu(rl->rl_exflags);
|
||||||
lkb->lkb_flags = rl->rl_flags & 0x0000FFFF;
|
lkb->lkb_flags = le32_to_cpu(rl->rl_flags) & 0x0000FFFF;
|
||||||
lkb->lkb_flags |= DLM_IFL_MSTCPY;
|
lkb->lkb_flags |= DLM_IFL_MSTCPY;
|
||||||
lkb->lkb_lvbseq = rl->rl_lvbseq;
|
lkb->lkb_lvbseq = le32_to_cpu(rl->rl_lvbseq);
|
||||||
lkb->lkb_rqmode = rl->rl_rqmode;
|
lkb->lkb_rqmode = rl->rl_rqmode;
|
||||||
lkb->lkb_grmode = rl->rl_grmode;
|
lkb->lkb_grmode = rl->rl_grmode;
|
||||||
/* don't set lkb_status because add_lkb wants to itself */
|
/* don't set lkb_status because add_lkb wants to itself */
|
||||||
|
|
||||||
lkb->lkb_bastaddr = (void *) (long) (rl->rl_asts & AST_BAST);
|
lkb->lkb_bastfn = (rl->rl_asts & AST_BAST) ? &fake_bastfn : NULL;
|
||||||
lkb->lkb_astaddr = (void *) (long) (rl->rl_asts & AST_COMP);
|
lkb->lkb_astfn = (rl->rl_asts & AST_COMP) ? &fake_astfn : NULL;
|
||||||
|
|
||||||
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
|
if (lkb->lkb_exflags & DLM_LKF_VALBLK) {
|
||||||
|
int lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
|
||||||
|
sizeof(struct rcom_lock);
|
||||||
|
if (lvblen > ls->ls_lvblen)
|
||||||
|
return -EINVAL;
|
||||||
lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
|
lkb->lkb_lvbptr = dlm_allocate_lvb(ls);
|
||||||
if (!lkb->lkb_lvbptr)
|
if (!lkb->lkb_lvbptr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
lvblen = rc->rc_header.h_length - sizeof(struct dlm_rcom) -
|
|
||||||
sizeof(struct rcom_lock);
|
|
||||||
memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen);
|
memcpy(lkb->lkb_lvbptr, rl->rl_lvb, lvblen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4300,7 +4323,8 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
|||||||
The real granted mode of these converting locks cannot be determined
|
The real granted mode of these converting locks cannot be determined
|
||||||
until all locks have been rebuilt on the rsb (recover_conversion) */
|
until all locks have been rebuilt on the rsb (recover_conversion) */
|
||||||
|
|
||||||
if (rl->rl_wait_type == DLM_MSG_CONVERT && middle_conversion(lkb)) {
|
if (rl->rl_wait_type == cpu_to_le16(DLM_MSG_CONVERT) &&
|
||||||
|
middle_conversion(lkb)) {
|
||||||
rl->rl_status = DLM_LKSTS_CONVERT;
|
rl->rl_status = DLM_LKSTS_CONVERT;
|
||||||
lkb->lkb_grmode = DLM_LOCK_IV;
|
lkb->lkb_grmode = DLM_LOCK_IV;
|
||||||
rsb_set_flag(r, RSB_RECOVER_CONVERT);
|
rsb_set_flag(r, RSB_RECOVER_CONVERT);
|
||||||
@ -4315,6 +4339,7 @@ static int receive_rcom_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
|
|||||||
the given values and send back our lkid. We send back our lkid by sending
|
the given values and send back our lkid. We send back our lkid by sending
|
||||||
back the rcom_lock struct we got but with the remid field filled in. */
|
back the rcom_lock struct we got but with the remid field filled in. */
|
||||||
|
|
||||||
|
/* needs at least dlm_rcom + rcom_lock */
|
||||||
int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
||||||
{
|
{
|
||||||
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
||||||
@ -4327,13 +4352,14 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = find_rsb(ls, rl->rl_name, rl->rl_namelen, R_MASTER, &r);
|
error = find_rsb(ls, rl->rl_name, le16_to_cpu(rl->rl_namelen),
|
||||||
|
R_MASTER, &r);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
lock_rsb(r);
|
lock_rsb(r);
|
||||||
|
|
||||||
lkb = search_remid(r, rc->rc_header.h_nodeid, rl->rl_lkid);
|
lkb = search_remid(r, rc->rc_header.h_nodeid, le32_to_cpu(rl->rl_lkid));
|
||||||
if (lkb) {
|
if (lkb) {
|
||||||
error = -EEXIST;
|
error = -EEXIST;
|
||||||
goto out_remid;
|
goto out_remid;
|
||||||
@ -4356,18 +4382,20 @@ int dlm_recover_master_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
|||||||
out_remid:
|
out_remid:
|
||||||
/* this is the new value returned to the lock holder for
|
/* this is the new value returned to the lock holder for
|
||||||
saving in its process-copy lkb */
|
saving in its process-copy lkb */
|
||||||
rl->rl_remid = lkb->lkb_id;
|
rl->rl_remid = cpu_to_le32(lkb->lkb_id);
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
unlock_rsb(r);
|
unlock_rsb(r);
|
||||||
put_rsb(r);
|
put_rsb(r);
|
||||||
out:
|
out:
|
||||||
if (error)
|
if (error)
|
||||||
log_debug(ls, "recover_master_copy %d %x", error, rl->rl_lkid);
|
log_debug(ls, "recover_master_copy %d %x", error,
|
||||||
rl->rl_result = error;
|
le32_to_cpu(rl->rl_lkid));
|
||||||
|
rl->rl_result = cpu_to_le32(error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* needs at least dlm_rcom + rcom_lock */
|
||||||
int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
||||||
{
|
{
|
||||||
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
struct rcom_lock *rl = (struct rcom_lock *) rc->rc_buf;
|
||||||
@ -4375,15 +4403,16 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
|||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = find_lkb(ls, rl->rl_lkid, &lkb);
|
error = find_lkb(ls, le32_to_cpu(rl->rl_lkid), &lkb);
|
||||||
if (error) {
|
if (error) {
|
||||||
log_error(ls, "recover_process_copy no lkid %x", rl->rl_lkid);
|
log_error(ls, "recover_process_copy no lkid %x",
|
||||||
|
le32_to_cpu(rl->rl_lkid));
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
|
DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb););
|
||||||
|
|
||||||
error = rl->rl_result;
|
error = le32_to_cpu(rl->rl_result);
|
||||||
|
|
||||||
r = lkb->lkb_resource;
|
r = lkb->lkb_resource;
|
||||||
hold_rsb(r);
|
hold_rsb(r);
|
||||||
@ -4402,7 +4431,7 @@ int dlm_recover_process_copy(struct dlm_ls *ls, struct dlm_rcom *rc)
|
|||||||
log_debug(ls, "master copy exists %x", lkb->lkb_id);
|
log_debug(ls, "master copy exists %x", lkb->lkb_id);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 0:
|
case 0:
|
||||||
lkb->lkb_remid = rl->rl_remid;
|
lkb->lkb_remid = le32_to_cpu(rl->rl_remid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_error(ls, "dlm_recover_process_copy unknown error %d %x",
|
log_error(ls, "dlm_recover_process_copy unknown error %d %x",
|
||||||
@ -4451,7 +4480,7 @@ int dlm_user_request(struct dlm_ls *ls, struct dlm_user_args *ua,
|
|||||||
lock and that lkb_astparam is the dlm_user_args structure. */
|
lock and that lkb_astparam is the dlm_user_args structure. */
|
||||||
|
|
||||||
error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
|
error = set_lock_args(mode, &ua->lksb, flags, namelen, timeout_cs,
|
||||||
DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
|
fake_astfn, ua, fake_bastfn, &args);
|
||||||
lkb->lkb_flags |= DLM_IFL_USER;
|
lkb->lkb_flags |= DLM_IFL_USER;
|
||||||
ua->old_mode = DLM_LOCK_IV;
|
ua->old_mode = DLM_LOCK_IV;
|
||||||
|
|
||||||
@ -4504,7 +4533,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|||||||
/* user can change the params on its lock when it converts it, or
|
/* user can change the params on its lock when it converts it, or
|
||||||
add an lvb that didn't exist before */
|
add an lvb that didn't exist before */
|
||||||
|
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
|
|
||||||
if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
|
if (flags & DLM_LKF_VALBLK && !ua->lksb.sb_lvbptr) {
|
||||||
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
|
ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_KERNEL);
|
||||||
@ -4525,7 +4554,7 @@ int dlm_user_convert(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|||||||
ua->old_mode = lkb->lkb_grmode;
|
ua->old_mode = lkb->lkb_grmode;
|
||||||
|
|
||||||
error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
|
error = set_lock_args(mode, &ua->lksb, flags, 0, timeout_cs,
|
||||||
DLM_FAKE_USER_AST, ua, DLM_FAKE_USER_AST, &args);
|
fake_astfn, ua, fake_bastfn, &args);
|
||||||
if (error)
|
if (error)
|
||||||
goto out_put;
|
goto out_put;
|
||||||
|
|
||||||
@ -4555,7 +4584,7 @@ int dlm_user_unlock(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
|
|
||||||
if (lvb_in && ua->lksb.sb_lvbptr)
|
if (lvb_in && ua->lksb.sb_lvbptr)
|
||||||
memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
|
memcpy(ua->lksb.sb_lvbptr, lvb_in, DLM_USER_LVB_LEN);
|
||||||
@ -4604,7 +4633,7 @@ int dlm_user_cancel(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
|
|||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
if (ua_tmp->castparam)
|
if (ua_tmp->castparam)
|
||||||
ua->castparam = ua_tmp->castparam;
|
ua->castparam = ua_tmp->castparam;
|
||||||
ua->user_lksb = ua_tmp->user_lksb;
|
ua->user_lksb = ua_tmp->user_lksb;
|
||||||
@ -4642,7 +4671,7 @@ int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid)
|
|||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
|
|
||||||
error = set_unlock_args(flags, ua, &args);
|
error = set_unlock_args(flags, ua, &args);
|
||||||
if (error)
|
if (error)
|
||||||
@ -4681,7 +4710,6 @@ int dlm_user_deadlock(struct dlm_ls *ls, uint32_t flags, uint32_t lkid)
|
|||||||
|
|
||||||
static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
||||||
{
|
{
|
||||||
struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
|
||||||
struct dlm_args args;
|
struct dlm_args args;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -4690,7 +4718,7 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
|||||||
list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
|
list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
|
||||||
mutex_unlock(&ls->ls_orphans_mutex);
|
mutex_unlock(&ls->ls_orphans_mutex);
|
||||||
|
|
||||||
set_unlock_args(0, ua, &args);
|
set_unlock_args(0, lkb->lkb_ua, &args);
|
||||||
|
|
||||||
error = cancel_lock(ls, lkb, &args);
|
error = cancel_lock(ls, lkb, &args);
|
||||||
if (error == -DLM_ECANCEL)
|
if (error == -DLM_ECANCEL)
|
||||||
@ -4703,11 +4731,10 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
|||||||
|
|
||||||
static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
|
||||||
{
|
{
|
||||||
struct dlm_user_args *ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
|
||||||
struct dlm_args args;
|
struct dlm_args args;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
set_unlock_args(DLM_LKF_FORCEUNLOCK, ua, &args);
|
set_unlock_args(DLM_LKF_FORCEUNLOCK, lkb->lkb_ua, &args);
|
||||||
|
|
||||||
error = unlock_lock(ls, lkb, &args);
|
error = unlock_lock(ls, lkb, &args);
|
||||||
if (error == -DLM_EUNLOCK)
|
if (error == -DLM_EUNLOCK)
|
||||||
|
@ -17,7 +17,7 @@ void dlm_print_rsb(struct dlm_rsb *r);
|
|||||||
void dlm_dump_rsb(struct dlm_rsb *r);
|
void dlm_dump_rsb(struct dlm_rsb *r);
|
||||||
void dlm_print_lkb(struct dlm_lkb *lkb);
|
void dlm_print_lkb(struct dlm_lkb *lkb);
|
||||||
void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
|
void dlm_receive_message_saved(struct dlm_ls *ls, struct dlm_message *ms);
|
||||||
void dlm_receive_buffer(struct dlm_header *hd, int nodeid);
|
void dlm_receive_buffer(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);
|
||||||
|
@ -191,7 +191,7 @@ static int do_uevent(struct dlm_ls *ls, int in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dlm_lockspace_init(void)
|
int __init dlm_lockspace_init(void)
|
||||||
{
|
{
|
||||||
ls_count = 0;
|
ls_count = 0;
|
||||||
mutex_init(&ls_lock);
|
mutex_init(&ls_lock);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
static struct kmem_cache *lkb_cache;
|
static struct kmem_cache *lkb_cache;
|
||||||
|
|
||||||
|
|
||||||
int dlm_memory_init(void)
|
int __init dlm_memory_init(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
|
|||||||
{
|
{
|
||||||
if (lkb->lkb_flags & DLM_IFL_USER) {
|
if (lkb->lkb_flags & DLM_IFL_USER) {
|
||||||
struct dlm_user_args *ua;
|
struct dlm_user_args *ua;
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
if (ua) {
|
if (ua) {
|
||||||
if (ua->lksb.sb_lvbptr)
|
if (ua->lksb.sb_lvbptr)
|
||||||
kfree(ua->lksb.sb_lvbptr);
|
kfree(ua->lksb.sb_lvbptr);
|
||||||
|
@ -61,9 +61,9 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
|
|||||||
union {
|
union {
|
||||||
unsigned char __buf[DLM_INBUF_LEN];
|
unsigned char __buf[DLM_INBUF_LEN];
|
||||||
/* this is to force proper alignment on some arches */
|
/* this is to force proper alignment on some arches */
|
||||||
struct dlm_header dlm;
|
union dlm_packet p;
|
||||||
} __tmp;
|
} __tmp;
|
||||||
struct dlm_header *msg = &__tmp.dlm;
|
union dlm_packet *p = &__tmp.p;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
uint16_t msglen;
|
uint16_t msglen;
|
||||||
@ -75,15 +75,22 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
|
|||||||
message may wrap around the end of the buffer back to the
|
message may wrap around the end of the buffer back to the
|
||||||
start, so we need to use a temp buffer and copy_from_cb. */
|
start, so we need to use a temp buffer and copy_from_cb. */
|
||||||
|
|
||||||
copy_from_cb(msg, base, offset, sizeof(struct dlm_header),
|
copy_from_cb(p, base, offset, sizeof(struct dlm_header),
|
||||||
limit);
|
limit);
|
||||||
|
|
||||||
msglen = le16_to_cpu(msg->h_length);
|
msglen = le16_to_cpu(p->header.h_length);
|
||||||
lockspace = msg->h_lockspace;
|
lockspace = p->header.h_lockspace;
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (msglen < sizeof(struct dlm_header))
|
if (msglen < sizeof(struct dlm_header))
|
||||||
break;
|
break;
|
||||||
|
if (p->header.h_cmd == DLM_MSG) {
|
||||||
|
if (msglen < sizeof(struct dlm_message))
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (msglen < sizeof(struct dlm_rcom))
|
||||||
|
break;
|
||||||
|
}
|
||||||
err = -E2BIG;
|
err = -E2BIG;
|
||||||
if (msglen > dlm_config.ci_buffer_size) {
|
if (msglen > dlm_config.ci_buffer_size) {
|
||||||
log_print("message size %d from %d too big, buf len %d",
|
log_print("message size %d from %d too big, buf len %d",
|
||||||
@ -104,26 +111,26 @@ int dlm_process_incoming_buffer(int nodeid, const void *base,
|
|||||||
in the buffer on the stack (which should work for most
|
in the buffer on the stack (which should work for most
|
||||||
ordinary messages). */
|
ordinary messages). */
|
||||||
|
|
||||||
if (msglen > DLM_INBUF_LEN && msg == &__tmp.dlm) {
|
if (msglen > sizeof(__tmp) && p == &__tmp.p) {
|
||||||
msg = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
|
p = kmalloc(dlm_config.ci_buffer_size, GFP_KERNEL);
|
||||||
if (msg == NULL)
|
if (p == NULL)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_from_cb(msg, base, offset, msglen, limit);
|
copy_from_cb(p, base, offset, msglen, limit);
|
||||||
|
|
||||||
BUG_ON(lockspace != msg->h_lockspace);
|
BUG_ON(lockspace != p->header.h_lockspace);
|
||||||
|
|
||||||
ret += msglen;
|
ret += msglen;
|
||||||
offset += msglen;
|
offset += msglen;
|
||||||
offset &= (limit - 1);
|
offset &= (limit - 1);
|
||||||
len -= msglen;
|
len -= msglen;
|
||||||
|
|
||||||
dlm_receive_buffer(msg, nodeid);
|
dlm_receive_buffer(p, nodeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg != &__tmp.dlm)
|
if (p != &__tmp.p)
|
||||||
kfree(msg);
|
kfree(p);
|
||||||
|
|
||||||
return err ? err : ret;
|
return err ? err : ret;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ static struct genl_ops dlm_nl_ops = {
|
|||||||
.doit = user_cmd,
|
.doit = user_cmd,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dlm_netlink_init(void)
|
int __init dlm_netlink_init(void)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ int dlm_netlink_init(void)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_netlink_exit(void)
|
void __exit dlm_netlink_exit(void)
|
||||||
{
|
{
|
||||||
genl_unregister_ops(&family, &dlm_nl_ops);
|
genl_unregister_ops(&family, &dlm_nl_ops);
|
||||||
genl_unregister_family(&family);
|
genl_unregister_family(&family);
|
||||||
@ -104,7 +104,6 @@ void dlm_netlink_exit(void)
|
|||||||
static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
|
static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
|
||||||
{
|
{
|
||||||
struct dlm_rsb *r = lkb->lkb_resource;
|
struct dlm_rsb *r = lkb->lkb_resource;
|
||||||
struct dlm_user_args *ua = (struct dlm_user_args *) lkb->lkb_astparam;
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(struct dlm_lock_data));
|
memset(data, 0, sizeof(struct dlm_lock_data));
|
||||||
|
|
||||||
@ -117,8 +116,8 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
|
|||||||
data->grmode = lkb->lkb_grmode;
|
data->grmode = lkb->lkb_grmode;
|
||||||
data->rqmode = lkb->lkb_rqmode;
|
data->rqmode = lkb->lkb_rqmode;
|
||||||
data->timestamp = lkb->lkb_timestamp;
|
data->timestamp = lkb->lkb_timestamp;
|
||||||
if (ua)
|
if (lkb->lkb_ua)
|
||||||
data->xid = ua->xid;
|
data->xid = lkb->lkb_ua->xid;
|
||||||
if (r) {
|
if (r) {
|
||||||
data->lockspace_id = r->res_ls->ls_global_id;
|
data->lockspace_id = r->res_ls->ls_global_id;
|
||||||
data->resource_namelen = r->res_length;
|
data->resource_namelen = r->res_length;
|
||||||
|
@ -78,13 +78,14 @@ static void send_rcom(struct dlm_ls *ls, struct dlm_mhandle *mh,
|
|||||||
|
|
||||||
static void make_config(struct dlm_ls *ls, struct rcom_config *rf)
|
static void make_config(struct dlm_ls *ls, struct rcom_config *rf)
|
||||||
{
|
{
|
||||||
rf->rf_lvblen = ls->ls_lvblen;
|
rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen);
|
||||||
rf->rf_lsflags = ls->ls_exflags;
|
rf->rf_lsflags = cpu_to_le32(ls->ls_exflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
||||||
{
|
{
|
||||||
struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
|
struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
|
||||||
|
size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
|
||||||
|
|
||||||
if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) {
|
if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) {
|
||||||
log_error(ls, "version mismatch: %x nodeid %d: %x",
|
log_error(ls, "version mismatch: %x nodeid %d: %x",
|
||||||
@ -93,11 +94,18 @@ static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
|||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rf->rf_lvblen != ls->ls_lvblen ||
|
if (rc->rc_header.h_length < conf_size) {
|
||||||
rf->rf_lsflags != ls->ls_exflags) {
|
log_error(ls, "config too short: %d nodeid %d",
|
||||||
|
rc->rc_header.h_length, nodeid);
|
||||||
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen ||
|
||||||
|
le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) {
|
||||||
log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
|
log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
|
||||||
ls->ls_lvblen, ls->ls_exflags,
|
ls->ls_lvblen, ls->ls_exflags, nodeid,
|
||||||
nodeid, rf->rf_lvblen, rf->rf_lsflags);
|
le32_to_cpu(rf->rf_lvblen),
|
||||||
|
le32_to_cpu(rf->rf_lsflags));
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -128,7 +136,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
|
|||||||
ls->ls_recover_nodeid = nodeid;
|
ls->ls_recover_nodeid = nodeid;
|
||||||
|
|
||||||
if (nodeid == dlm_our_nodeid()) {
|
if (nodeid == dlm_our_nodeid()) {
|
||||||
rc = (struct dlm_rcom *) ls->ls_recover_buf;
|
rc = ls->ls_recover_buf;
|
||||||
rc->rc_result = dlm_recover_status(ls);
|
rc->rc_result = dlm_recover_status(ls);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -147,7 +155,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
|
|||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = (struct dlm_rcom *) ls->ls_recover_buf;
|
rc = ls->ls_recover_buf;
|
||||||
|
|
||||||
if (rc->rc_result == -ESRCH) {
|
if (rc->rc_result == -ESRCH) {
|
||||||
/* we pretend the remote lockspace exists with 0 status */
|
/* we pretend the remote lockspace exists with 0 status */
|
||||||
@ -201,14 +209,15 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len)
|
|||||||
{
|
{
|
||||||
struct dlm_rcom *rc;
|
struct dlm_rcom *rc;
|
||||||
struct dlm_mhandle *mh;
|
struct dlm_mhandle *mh;
|
||||||
int error = 0, len = sizeof(struct dlm_rcom);
|
int error = 0;
|
||||||
|
int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
|
||||||
|
|
||||||
ls->ls_recover_nodeid = nodeid;
|
ls->ls_recover_nodeid = nodeid;
|
||||||
|
|
||||||
if (nodeid == dlm_our_nodeid()) {
|
if (nodeid == dlm_our_nodeid()) {
|
||||||
dlm_copy_master_names(ls, last_name, last_len,
|
dlm_copy_master_names(ls, last_name, last_len,
|
||||||
ls->ls_recover_buf + len,
|
ls->ls_recover_buf->rc_buf,
|
||||||
dlm_config.ci_buffer_size - len, nodeid);
|
max_size, nodeid);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,22 +308,22 @@ static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb,
|
|||||||
{
|
{
|
||||||
memset(rl, 0, sizeof(*rl));
|
memset(rl, 0, sizeof(*rl));
|
||||||
|
|
||||||
rl->rl_ownpid = lkb->lkb_ownpid;
|
rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid);
|
||||||
rl->rl_lkid = lkb->lkb_id;
|
rl->rl_lkid = cpu_to_le32(lkb->lkb_id);
|
||||||
rl->rl_exflags = lkb->lkb_exflags;
|
rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags);
|
||||||
rl->rl_flags = lkb->lkb_flags;
|
rl->rl_flags = cpu_to_le32(lkb->lkb_flags);
|
||||||
rl->rl_lvbseq = lkb->lkb_lvbseq;
|
rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq);
|
||||||
rl->rl_rqmode = lkb->lkb_rqmode;
|
rl->rl_rqmode = lkb->lkb_rqmode;
|
||||||
rl->rl_grmode = lkb->lkb_grmode;
|
rl->rl_grmode = lkb->lkb_grmode;
|
||||||
rl->rl_status = lkb->lkb_status;
|
rl->rl_status = lkb->lkb_status;
|
||||||
rl->rl_wait_type = lkb->lkb_wait_type;
|
rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type);
|
||||||
|
|
||||||
if (lkb->lkb_bastaddr)
|
if (lkb->lkb_bastfn)
|
||||||
rl->rl_asts |= AST_BAST;
|
rl->rl_asts |= AST_BAST;
|
||||||
if (lkb->lkb_astaddr)
|
if (lkb->lkb_astfn)
|
||||||
rl->rl_asts |= AST_COMP;
|
rl->rl_asts |= AST_COMP;
|
||||||
|
|
||||||
rl->rl_namelen = r->res_length;
|
rl->rl_namelen = cpu_to_le16(r->res_length);
|
||||||
memcpy(rl->rl_name, r->res_name, r->res_length);
|
memcpy(rl->rl_name, r->res_name, r->res_length);
|
||||||
|
|
||||||
/* FIXME: might we have an lvb without DLM_LKF_VALBLK set ?
|
/* FIXME: might we have an lvb without DLM_LKF_VALBLK set ?
|
||||||
@ -348,6 +357,7 @@ int dlm_send_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* needs at least dlm_rcom + rcom_lock */
|
||||||
static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
|
||||||
{
|
{
|
||||||
struct dlm_rcom *rc;
|
struct dlm_rcom *rc;
|
||||||
@ -401,7 +411,7 @@ int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
|
|||||||
rc->rc_result = -ESRCH;
|
rc->rc_result = -ESRCH;
|
||||||
|
|
||||||
rf = (struct rcom_config *) rc->rc_buf;
|
rf = (struct rcom_config *) rc->rc_buf;
|
||||||
rf->rf_lvblen = -1;
|
rf->rf_lvblen = cpu_to_le32(~0U);
|
||||||
|
|
||||||
dlm_rcom_out(rc);
|
dlm_rcom_out(rc);
|
||||||
dlm_lowcomms_commit_buffer(mh);
|
dlm_lowcomms_commit_buffer(mh);
|
||||||
@ -439,6 +449,8 @@ static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
|
|||||||
|
|
||||||
void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
||||||
{
|
{
|
||||||
|
int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock);
|
||||||
|
|
||||||
if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
|
if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
|
||||||
log_debug(ls, "ignoring recovery message %x from %d",
|
log_debug(ls, "ignoring recovery message %x from %d",
|
||||||
rc->rc_type, nodeid);
|
rc->rc_type, nodeid);
|
||||||
@ -462,6 +474,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DLM_RCOM_LOCK:
|
case DLM_RCOM_LOCK:
|
||||||
|
if (rc->rc_header.h_length < lock_size)
|
||||||
|
goto Eshort;
|
||||||
receive_rcom_lock(ls, rc);
|
receive_rcom_lock(ls, rc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -478,6 +492,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DLM_RCOM_LOCK_REPLY:
|
case DLM_RCOM_LOCK_REPLY:
|
||||||
|
if (rc->rc_header.h_length < lock_size)
|
||||||
|
goto Eshort;
|
||||||
dlm_recover_process_copy(ls, rc);
|
dlm_recover_process_copy(ls, rc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -486,5 +502,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return;
|
return;
|
||||||
|
Eshort:
|
||||||
|
log_error(ls, "recovery message %x from %d is too short",
|
||||||
|
rc->rc_type, nodeid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,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)
|
||||||
{
|
{
|
||||||
struct dlm_rcom *rc = (struct dlm_rcom *) ls->ls_recover_buf;
|
struct dlm_rcom *rc = ls->ls_recover_buf;
|
||||||
struct dlm_member *memb;
|
struct dlm_member *memb;
|
||||||
int error = 0, delay;
|
int error = 0, delay;
|
||||||
|
|
||||||
@ -123,7 +123,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)
|
||||||
{
|
{
|
||||||
struct dlm_rcom *rc = (struct dlm_rcom *) 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;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
struct rq_entry {
|
struct rq_entry {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
int nodeid;
|
int nodeid;
|
||||||
char request[0];
|
struct dlm_message request;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -30,10 +30,10 @@ 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_header *hd)
|
void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_message *ms)
|
||||||
{
|
{
|
||||||
struct rq_entry *e;
|
struct rq_entry *e;
|
||||||
int length = hd->h_length;
|
int length = ms->m_header.h_length - sizeof(struct dlm_message);
|
||||||
|
|
||||||
e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL);
|
e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL);
|
||||||
if (!e) {
|
if (!e) {
|
||||||
@ -42,7 +42,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
e->nodeid = nodeid;
|
e->nodeid = nodeid;
|
||||||
memcpy(e->request, hd, length);
|
memcpy(&e->request, ms, ms->m_header.h_length);
|
||||||
|
|
||||||
mutex_lock(&ls->ls_requestqueue_mutex);
|
mutex_lock(&ls->ls_requestqueue_mutex);
|
||||||
list_add_tail(&e->list, &ls->ls_requestqueue);
|
list_add_tail(&e->list, &ls->ls_requestqueue);
|
||||||
@ -76,7 +76,7 @@ int dlm_process_requestqueue(struct dlm_ls *ls)
|
|||||||
e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list);
|
e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list);
|
||||||
mutex_unlock(&ls->ls_requestqueue_mutex);
|
mutex_unlock(&ls->ls_requestqueue_mutex);
|
||||||
|
|
||||||
dlm_receive_message_saved(ls, (struct dlm_message *)e->request);
|
dlm_receive_message_saved(ls, &e->request);
|
||||||
|
|
||||||
mutex_lock(&ls->ls_requestqueue_mutex);
|
mutex_lock(&ls->ls_requestqueue_mutex);
|
||||||
list_del(&e->list);
|
list_del(&e->list);
|
||||||
@ -176,7 +176,7 @@ void dlm_purge_requestqueue(struct dlm_ls *ls)
|
|||||||
|
|
||||||
mutex_lock(&ls->ls_requestqueue_mutex);
|
mutex_lock(&ls->ls_requestqueue_mutex);
|
||||||
list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) {
|
list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) {
|
||||||
ms = (struct dlm_message *) e->request;
|
ms = &e->request;
|
||||||
|
|
||||||
if (purge_request(ls, ms, e->nodeid)) {
|
if (purge_request(ls, ms, e->nodeid)) {
|
||||||
list_del(&e->list);
|
list_del(&e->list);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
#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_header *hd);
|
void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, 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);
|
||||||
|
@ -82,7 +82,7 @@ struct dlm_lock_result32 {
|
|||||||
|
|
||||||
static void compat_input(struct dlm_write_request *kb,
|
static void compat_input(struct dlm_write_request *kb,
|
||||||
struct dlm_write_request32 *kb32,
|
struct dlm_write_request32 *kb32,
|
||||||
int max_namelen)
|
size_t count)
|
||||||
{
|
{
|
||||||
kb->version[0] = kb32->version[0];
|
kb->version[0] = kb32->version[0];
|
||||||
kb->version[1] = kb32->version[1];
|
kb->version[1] = kb32->version[1];
|
||||||
@ -94,7 +94,8 @@ static void compat_input(struct dlm_write_request *kb,
|
|||||||
kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
|
kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
|
||||||
kb->i.lspace.flags = kb32->i.lspace.flags;
|
kb->i.lspace.flags = kb32->i.lspace.flags;
|
||||||
kb->i.lspace.minor = kb32->i.lspace.minor;
|
kb->i.lspace.minor = kb32->i.lspace.minor;
|
||||||
strcpy(kb->i.lspace.name, kb32->i.lspace.name);
|
memcpy(kb->i.lspace.name, kb32->i.lspace.name, count -
|
||||||
|
offsetof(struct dlm_write_request32, i.lspace.name));
|
||||||
} else if (kb->cmd == DLM_USER_PURGE) {
|
} else if (kb->cmd == DLM_USER_PURGE) {
|
||||||
kb->i.purge.nodeid = kb32->i.purge.nodeid;
|
kb->i.purge.nodeid = kb32->i.purge.nodeid;
|
||||||
kb->i.purge.pid = kb32->i.purge.pid;
|
kb->i.purge.pid = kb32->i.purge.pid;
|
||||||
@ -112,11 +113,8 @@ static void compat_input(struct dlm_write_request *kb,
|
|||||||
kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
|
kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
|
||||||
kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
|
kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
|
||||||
memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
|
memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
|
||||||
if (kb->i.lock.namelen <= max_namelen)
|
memcpy(kb->i.lock.name, kb32->i.lock.name, count -
|
||||||
memcpy(kb->i.lock.name, kb32->i.lock.name,
|
offsetof(struct dlm_write_request32, i.lock.name));
|
||||||
kb->i.lock.namelen);
|
|
||||||
else
|
|
||||||
kb->i.lock.namelen = max_namelen;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,8 +195,8 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type)
|
|||||||
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
|
if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
DLM_ASSERT(lkb->lkb_astparam, dlm_print_lkb(lkb););
|
DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb););
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
ua = lkb->lkb_ua;
|
||||||
proc = ua->proc;
|
proc = ua->proc;
|
||||||
|
|
||||||
if (type == AST_BAST && ua->bastaddr == NULL)
|
if (type == AST_BAST && ua->bastaddr == NULL)
|
||||||
@ -508,7 +506,7 @@ static ssize_t device_write(struct file *file, const char __user *buf,
|
|||||||
#endif
|
#endif
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
kbuf = kmalloc(count, GFP_KERNEL);
|
kbuf = kzalloc(count + 1, GFP_KERNEL);
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -526,15 +524,14 @@ static ssize_t device_write(struct file *file, const char __user *buf,
|
|||||||
if (!kbuf->is64bit) {
|
if (!kbuf->is64bit) {
|
||||||
struct dlm_write_request32 *k32buf;
|
struct dlm_write_request32 *k32buf;
|
||||||
k32buf = (struct dlm_write_request32 *)kbuf;
|
k32buf = (struct dlm_write_request32 *)kbuf;
|
||||||
kbuf = kmalloc(count + (sizeof(struct dlm_write_request) -
|
kbuf = kmalloc(count + 1 + (sizeof(struct dlm_write_request) -
|
||||||
sizeof(struct dlm_write_request32)), GFP_KERNEL);
|
sizeof(struct dlm_write_request32)), GFP_KERNEL);
|
||||||
if (!kbuf)
|
if (!kbuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (proc)
|
if (proc)
|
||||||
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
|
set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
|
||||||
compat_input(kbuf, k32buf,
|
compat_input(kbuf, k32buf, count + 1);
|
||||||
count - sizeof(struct dlm_write_request32));
|
|
||||||
kfree(k32buf);
|
kfree(k32buf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -774,7 +771,6 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
|
|||||||
{
|
{
|
||||||
struct dlm_user_proc *proc = file->private_data;
|
struct dlm_user_proc *proc = file->private_data;
|
||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
struct dlm_user_args *ua;
|
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
int error, type=0, bmode=0, removed = 0;
|
int error, type=0, bmode=0, removed = 0;
|
||||||
|
|
||||||
@ -845,8 +841,7 @@ static ssize_t device_read(struct file *file, char __user *buf, size_t count,
|
|||||||
}
|
}
|
||||||
spin_unlock(&proc->asts_spin);
|
spin_unlock(&proc->asts_spin);
|
||||||
|
|
||||||
ua = (struct dlm_user_args *)lkb->lkb_astparam;
|
error = copy_result_to_user(lkb->lkb_ua,
|
||||||
error = copy_result_to_user(ua,
|
|
||||||
test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
|
test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
|
||||||
type, bmode, buf, count);
|
type, bmode, buf, count);
|
||||||
|
|
||||||
@ -907,7 +902,7 @@ static struct miscdevice ctl_device = {
|
|||||||
.minor = MISC_DYNAMIC_MINOR,
|
.minor = MISC_DYNAMIC_MINOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dlm_user_init(void)
|
int __init dlm_user_init(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -131,52 +131,8 @@ void dlm_message_in(struct dlm_message *ms)
|
|||||||
ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
|
ms->m_result = from_dlm_errno(le32_to_cpu(ms->m_result));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcom_lock_out(struct rcom_lock *rl)
|
|
||||||
{
|
|
||||||
rl->rl_ownpid = cpu_to_le32(rl->rl_ownpid);
|
|
||||||
rl->rl_lkid = cpu_to_le32(rl->rl_lkid);
|
|
||||||
rl->rl_remid = cpu_to_le32(rl->rl_remid);
|
|
||||||
rl->rl_parent_lkid = cpu_to_le32(rl->rl_parent_lkid);
|
|
||||||
rl->rl_parent_remid = cpu_to_le32(rl->rl_parent_remid);
|
|
||||||
rl->rl_exflags = cpu_to_le32(rl->rl_exflags);
|
|
||||||
rl->rl_flags = cpu_to_le32(rl->rl_flags);
|
|
||||||
rl->rl_lvbseq = cpu_to_le32(rl->rl_lvbseq);
|
|
||||||
rl->rl_result = cpu_to_le32(rl->rl_result);
|
|
||||||
rl->rl_wait_type = cpu_to_le16(rl->rl_wait_type);
|
|
||||||
rl->rl_namelen = cpu_to_le16(rl->rl_namelen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rcom_lock_in(struct rcom_lock *rl)
|
|
||||||
{
|
|
||||||
rl->rl_ownpid = le32_to_cpu(rl->rl_ownpid);
|
|
||||||
rl->rl_lkid = le32_to_cpu(rl->rl_lkid);
|
|
||||||
rl->rl_remid = le32_to_cpu(rl->rl_remid);
|
|
||||||
rl->rl_parent_lkid = le32_to_cpu(rl->rl_parent_lkid);
|
|
||||||
rl->rl_parent_remid = le32_to_cpu(rl->rl_parent_remid);
|
|
||||||
rl->rl_exflags = le32_to_cpu(rl->rl_exflags);
|
|
||||||
rl->rl_flags = le32_to_cpu(rl->rl_flags);
|
|
||||||
rl->rl_lvbseq = le32_to_cpu(rl->rl_lvbseq);
|
|
||||||
rl->rl_result = le32_to_cpu(rl->rl_result);
|
|
||||||
rl->rl_wait_type = le16_to_cpu(rl->rl_wait_type);
|
|
||||||
rl->rl_namelen = le16_to_cpu(rl->rl_namelen);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rcom_config_out(struct rcom_config *rf)
|
|
||||||
{
|
|
||||||
rf->rf_lvblen = cpu_to_le32(rf->rf_lvblen);
|
|
||||||
rf->rf_lsflags = cpu_to_le32(rf->rf_lsflags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rcom_config_in(struct rcom_config *rf)
|
|
||||||
{
|
|
||||||
rf->rf_lvblen = le32_to_cpu(rf->rf_lvblen);
|
|
||||||
rf->rf_lsflags = le32_to_cpu(rf->rf_lsflags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dlm_rcom_out(struct dlm_rcom *rc)
|
void dlm_rcom_out(struct dlm_rcom *rc)
|
||||||
{
|
{
|
||||||
int type = rc->rc_type;
|
|
||||||
|
|
||||||
header_out(&rc->rc_header);
|
header_out(&rc->rc_header);
|
||||||
|
|
||||||
rc->rc_type = cpu_to_le32(rc->rc_type);
|
rc->rc_type = cpu_to_le32(rc->rc_type);
|
||||||
@ -184,18 +140,10 @@ void dlm_rcom_out(struct dlm_rcom *rc)
|
|||||||
rc->rc_id = cpu_to_le64(rc->rc_id);
|
rc->rc_id = cpu_to_le64(rc->rc_id);
|
||||||
rc->rc_seq = cpu_to_le64(rc->rc_seq);
|
rc->rc_seq = cpu_to_le64(rc->rc_seq);
|
||||||
rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply);
|
rc->rc_seq_reply = cpu_to_le64(rc->rc_seq_reply);
|
||||||
|
|
||||||
if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
|
|
||||||
rcom_lock_out((struct rcom_lock *) rc->rc_buf);
|
|
||||||
|
|
||||||
else if (type == DLM_RCOM_STATUS_REPLY)
|
|
||||||
rcom_config_out((struct rcom_config *) rc->rc_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_rcom_in(struct dlm_rcom *rc)
|
void dlm_rcom_in(struct dlm_rcom *rc)
|
||||||
{
|
{
|
||||||
int type;
|
|
||||||
|
|
||||||
header_in(&rc->rc_header);
|
header_in(&rc->rc_header);
|
||||||
|
|
||||||
rc->rc_type = le32_to_cpu(rc->rc_type);
|
rc->rc_type = le32_to_cpu(rc->rc_type);
|
||||||
@ -203,13 +151,4 @@ void dlm_rcom_in(struct dlm_rcom *rc)
|
|||||||
rc->rc_id = le64_to_cpu(rc->rc_id);
|
rc->rc_id = le64_to_cpu(rc->rc_id);
|
||||||
rc->rc_seq = le64_to_cpu(rc->rc_seq);
|
rc->rc_seq = le64_to_cpu(rc->rc_seq);
|
||||||
rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
|
rc->rc_seq_reply = le64_to_cpu(rc->rc_seq_reply);
|
||||||
|
|
||||||
type = rc->rc_type;
|
|
||||||
|
|
||||||
if ((type == DLM_RCOM_LOCK) || (type == DLM_RCOM_LOCK_REPLY))
|
|
||||||
rcom_lock_in((struct rcom_lock *) rc->rc_buf);
|
|
||||||
|
|
||||||
else if (type == DLM_RCOM_STATUS_REPLY)
|
|
||||||
rcom_config_in((struct rcom_config *) rc->rc_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user