diff options
Diffstat (limited to 'fs/dlm/rcom.c')
-rw-r--r-- | fs/dlm/rcom.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index ac5c616c969..64d3e2b958c 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -486,47 +486,50 @@ int dlm_send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | |||
486 | return 0; | 486 | return 0; |
487 | } | 487 | } |
488 | 488 | ||
489 | static int is_old_reply(struct dlm_ls *ls, struct dlm_rcom *rc) | 489 | /* Called by dlm_recv; corresponds to dlm_receive_message() but special |
490 | recovery-only comms are sent through here. */ | ||
491 | |||
492 | void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | ||
490 | { | 493 | { |
494 | int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock); | ||
495 | int stop, reply = 0, lock = 0; | ||
496 | uint32_t status; | ||
491 | uint64_t seq; | 497 | uint64_t seq; |
492 | int rv = 0; | ||
493 | 498 | ||
494 | switch (rc->rc_type) { | 499 | switch (rc->rc_type) { |
500 | case DLM_RCOM_LOCK: | ||
501 | lock = 1; | ||
502 | break; | ||
503 | case DLM_RCOM_LOCK_REPLY: | ||
504 | lock = 1; | ||
505 | reply = 1; | ||
506 | break; | ||
495 | case DLM_RCOM_STATUS_REPLY: | 507 | case DLM_RCOM_STATUS_REPLY: |
496 | case DLM_RCOM_NAMES_REPLY: | 508 | case DLM_RCOM_NAMES_REPLY: |
497 | case DLM_RCOM_LOOKUP_REPLY: | 509 | case DLM_RCOM_LOOKUP_REPLY: |
498 | case DLM_RCOM_LOCK_REPLY: | 510 | reply = 1; |
499 | spin_lock(&ls->ls_recover_lock); | 511 | }; |
500 | seq = ls->ls_recover_seq; | ||
501 | spin_unlock(&ls->ls_recover_lock); | ||
502 | if (rc->rc_seq_reply != seq) { | ||
503 | log_debug(ls, "ignoring old reply %x from %d " | ||
504 | "seq_reply %llx expect %llx", | ||
505 | rc->rc_type, rc->rc_header.h_nodeid, | ||
506 | (unsigned long long)rc->rc_seq_reply, | ||
507 | (unsigned long long)seq); | ||
508 | rv = 1; | ||
509 | } | ||
510 | } | ||
511 | return rv; | ||
512 | } | ||
513 | |||
514 | /* Called by dlm_recv; corresponds to dlm_receive_message() but special | ||
515 | recovery-only comms are sent through here. */ | ||
516 | 512 | ||
517 | void dlm_receive_rcom(struct dlm_ls *ls, struct dlm_rcom *rc, int nodeid) | 513 | spin_lock(&ls->ls_recover_lock); |
518 | { | 514 | status = ls->ls_recover_status; |
519 | int lock_size = sizeof(struct dlm_rcom) + sizeof(struct rcom_lock); | 515 | stop = test_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); |
516 | seq = ls->ls_recover_seq; | ||
517 | spin_unlock(&ls->ls_recover_lock); | ||
520 | 518 | ||
521 | if (dlm_recovery_stopped(ls) && (rc->rc_type != DLM_RCOM_STATUS)) { | 519 | if ((stop && (rc->rc_type != DLM_RCOM_STATUS)) || |
522 | log_debug(ls, "ignoring recovery message %x from %d", | 520 | (reply && (rc->rc_seq_reply != seq)) || |
523 | rc->rc_type, nodeid); | 521 | (lock && !(status & DLM_RS_DIR))) { |
522 | log_limit(ls, "dlm_receive_rcom ignore msg %d " | ||
523 | "from %d %llu %llu recover seq %llu sts %x gen %u", | ||
524 | rc->rc_type, | ||
525 | nodeid, | ||
526 | (unsigned long long)rc->rc_seq, | ||
527 | (unsigned long long)rc->rc_seq_reply, | ||
528 | (unsigned long long)seq, | ||
529 | status, ls->ls_generation); | ||
524 | goto out; | 530 | goto out; |
525 | } | 531 | } |
526 | 532 | ||
527 | if (is_old_reply(ls, rc)) | ||
528 | goto out; | ||
529 | |||
530 | switch (rc->rc_type) { | 533 | switch (rc->rc_type) { |
531 | case DLM_RCOM_STATUS: | 534 | case DLM_RCOM_STATUS: |
532 | receive_rcom_status(ls, rc); | 535 | receive_rcom_status(ls, rc); |