diff options
Diffstat (limited to 'fs/dlm/rcom.c')
-rw-r--r-- | fs/dlm/rcom.c | 63 |
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 | ||
79 | static void make_config(struct dlm_ls *ls, struct rcom_config *rf) | 79 | static 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 | ||
85 | static int check_config(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | 85 | static 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 */ | ||
351 | static void receive_rcom_lock(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 361 | static 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 | ||
440 | void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | 450 | void 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: | 503 | out: |
488 | return; | 504 | return; |
505 | Eshort: | ||
506 | log_error(ls, "recovery message %x from %d is too short", | ||
507 | rc->rc_type, nodeid); | ||
489 | } | 508 | } |
490 | 509 | ||