aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm/rcom.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm/rcom.c')
-rw-r--r--fs/dlm/rcom.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c
index 026824cd3acb..035e6f9990b0 100644
--- a/fs/dlm/rcom.c
+++ b/fs/dlm/rcom.c
@@ -78,13 +78,14 @@ static void send_rcom(struct dlm_ls *ls, struct dlm_mhandle *mh,
78 78
79static void make_config(struct dlm_ls *ls, struct rcom_config *rf) 79static void make_config(struct dlm_ls *ls, struct rcom_config *rf)
80{ 80{
81 rf->rf_lvblen = ls->ls_lvblen; 81 rf->rf_lvblen = cpu_to_le32(ls->ls_lvblen);
82 rf->rf_lsflags = ls->ls_exflags; 82 rf->rf_lsflags = cpu_to_le32(ls->ls_exflags);
83} 83}
84 84
85static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) 85static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
86{ 86{
87 struct rcom_config *rf = (struct rcom_config *) rc->rc_buf; 87 struct rcom_config *rf = (struct rcom_config *) rc->rc_buf;
88 size_t conf_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_config);
88 89
89 if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) { 90 if ((rc->rc_header.h_version & 0xFFFF0000) != DLM_HEADER_MAJOR) {
90 log_error(ls, "version mismatch: %x nodeid %d: %x", 91 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)
93 return -EPROTO; 94 return -EPROTO;
94 } 95 }
95 96
96 if (rf->rf_lvblen != ls->ls_lvblen || 97 if (rc->rc_header.h_length < conf_size) {
97 rf->rf_lsflags != ls->ls_exflags) { 98 log_error(ls, "config too short: %d nodeid %d",
99 rc->rc_header.h_length, nodeid);
100 return -EPROTO;
101 }
102
103 if (le32_to_cpu(rf->rf_lvblen) != ls->ls_lvblen ||
104 le32_to_cpu(rf->rf_lsflags) != ls->ls_exflags) {
98 log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x", 105 log_error(ls, "config mismatch: %d,%x nodeid %d: %d,%x",
99 ls->ls_lvblen, ls->ls_exflags, 106 ls->ls_lvblen, ls->ls_exflags, nodeid,
100 nodeid, rf->rf_lvblen, rf->rf_lsflags); 107 le32_to_cpu(rf->rf_lvblen),
108 le32_to_cpu(rf->rf_lsflags));
101 return -EPROTO; 109 return -EPROTO;
102 } 110 }
103 return 0; 111 return 0;
@@ -128,7 +136,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
128 ls->ls_recover_nodeid = nodeid; 136 ls->ls_recover_nodeid = nodeid;
129 137
130 if (nodeid == dlm_our_nodeid()) { 138 if (nodeid == dlm_our_nodeid()) {
131 rc = (struct dlm_rcom *) ls->ls_recover_buf; 139 rc = ls->ls_recover_buf;
132 rc->rc_result = dlm_recover_status(ls); 140 rc->rc_result = dlm_recover_status(ls);
133 goto out; 141 goto out;
134 } 142 }
@@ -147,7 +155,7 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid)
147 if (error) 155 if (error)
148 goto out; 156 goto out;
149 157
150 rc = (struct dlm_rcom *) ls->ls_recover_buf; 158 rc = ls->ls_recover_buf;
151 159
152 if (rc->rc_result == -ESRCH) { 160 if (rc->rc_result == -ESRCH) {
153 /* we pretend the remote lockspace exists with 0 status */ 161 /* 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)
201{ 209{
202 struct dlm_rcom *rc; 210 struct dlm_rcom *rc;
203 struct dlm_mhandle *mh; 211 struct dlm_mhandle *mh;
204 int error = 0, len = sizeof(struct dlm_rcom); 212 int error = 0;
213 int max_size = dlm_config.ci_buffer_size - sizeof(struct dlm_rcom);
205 214
206 ls->ls_recover_nodeid = nodeid; 215 ls->ls_recover_nodeid = nodeid;
207 216
208 if (nodeid == dlm_our_nodeid()) { 217 if (nodeid == dlm_our_nodeid()) {
209 dlm_copy_master_names(ls, last_name, last_len, 218 dlm_copy_master_names(ls, last_name, last_len,
210 ls->ls_recover_buf + len, 219 ls->ls_recover_buf->rc_buf,
211 dlm_config.ci_buffer_size - len, nodeid); 220 max_size, nodeid);
212 goto out; 221 goto out;
213 } 222 }
214 223
@@ -299,22 +308,22 @@ static void pack_rcom_lock(struct dlm_rsb *r, struct dlm_lkb *lkb,
299{ 308{
300 memset(rl, 0, sizeof(*rl)); 309 memset(rl, 0, sizeof(*rl));
301 310
302 rl->rl_ownpid = lkb->lkb_ownpid; 311 rl->rl_ownpid = cpu_to_le32(lkb->lkb_ownpid);
303 rl->rl_lkid = lkb->lkb_id; 312 rl->rl_lkid = cpu_to_le32(lkb->lkb_id);
304 rl->rl_exflags = lkb->lkb_exflags; 313 rl->rl_exflags = cpu_to_le32(lkb->lkb_exflags);
305 rl->rl_flags = lkb->lkb_flags; 314 rl->rl_flags = cpu_to_le32(lkb->lkb_flags);
306 rl->rl_lvbseq = lkb->lkb_lvbseq; 315 rl->rl_lvbseq = cpu_to_le32(lkb->lkb_lvbseq);
307 rl->rl_rqmode = lkb->lkb_rqmode; 316 rl->rl_rqmode = lkb->lkb_rqmode;
308 rl->rl_grmode = lkb->lkb_grmode; 317 rl->rl_grmode = lkb->lkb_grmode;
309 rl->rl_status = lkb->lkb_status; 318 rl->rl_status = lkb->lkb_status;
310 rl->rl_wait_type = lkb->lkb_wait_type; 319 rl->rl_wait_type = cpu_to_le16(lkb->lkb_wait_type);
311 320
312 if (lkb->lkb_bastaddr) 321 if (lkb->lkb_bastfn)
313 rl->rl_asts |= AST_BAST; 322 rl->rl_asts |= AST_BAST;
314 if (lkb->lkb_astaddr) 323 if (lkb->lkb_astfn)
315 rl->rl_asts |= AST_COMP; 324 rl->rl_asts |= AST_COMP;
316 325
317 rl->rl_namelen = r->res_length; 326 rl->rl_namelen = cpu_to_le16(r->res_length);
318 memcpy(rl->rl_name, r->res_name, r->res_length); 327 memcpy(rl->rl_name, r->res_name, r->res_length);
319 328
320 /* FIXME: might we have an lvb without DLM_LKF_VALBLK set ? 329 /* 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)
348 return error; 357 return error;
349} 358}
350 359
360/* needs at least dlm_rcom + rcom_lock */
351static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) 361static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in)
352{ 362{
353 struct dlm_rcom *rc; 363 struct dlm_rcom *rc;
@@ -401,7 +411,7 @@ int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in)
401 rc->rc_result = -ESRCH; 411 rc->rc_result = -ESRCH;
402 412
403 rf = (struct rcom_config *) rc->rc_buf; 413 rf = (struct rcom_config *) rc->rc_buf;
404 rf->rf_lvblen = -1; 414 rf->rf_lvblen = cpu_to_le32(~0U);
405 415
406 dlm_rcom_out(rc); 416 dlm_rcom_out(rc);
407 dlm_lowcomms_commit_buffer(mh); 417 dlm_lowcomms_commit_buffer(mh);
@@ -439,6 +449,8 @@ static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc)
439 449
440void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) 450void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
441{ 451{
452 int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock);
453
442 if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { 454 if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) {
443 log_debug(ls, "ignoring recovery message %x from %d", 455 log_debug(ls, "ignoring recovery message %x from %d",
444 rc->rc_type, nodeid); 456 rc->rc_type, nodeid);
@@ -462,6 +474,8 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
462 break; 474 break;
463 475
464 case DLM_RCOM_LOCK: 476 case DLM_RCOM_LOCK:
477 if (rc->rc_header.h_length < lock_size)
478 goto Eshort;
465 receive_rcom_lock(ls, rc); 479 receive_rcom_lock(ls, rc);
466 break; 480 break;
467 481
@@ -478,13 +492,18 @@ void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid)
478 break; 492 break;
479 493
480 case DLM_RCOM_LOCK_REPLY: 494 case DLM_RCOM_LOCK_REPLY:
495 if (rc->rc_header.h_length < lock_size)
496 goto Eshort;
481 dlm_recover_process_copy(ls, rc); 497 dlm_recover_process_copy(ls, rc);
482 break; 498 break;
483 499
484 default: 500 default:
485 log_error(ls, "receive_rcom bad type %d", rc->rc_type); 501 log_error(ls, "receive_rcom bad type %d", rc->rc_type);
486 } 502 }
487 out: 503out:
488 return; 504 return;
505Eshort:
506 log_error(ls, "recovery message %x from %d is too short",
507 rc->rc_type, nodeid);
489} 508}
490 509