diff options
-rw-r--r-- | fs/dlm/lock.c | 139 |
1 files changed, 104 insertions, 35 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index c3b9fca17044..c2890efb0259 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -3008,8 +3008,6 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
3008 | lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); | 3008 | lkb->lkb_bastaddr = (void *) (long) (ms->m_asts & AST_BAST); |
3009 | lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); | 3009 | lkb->lkb_astaddr = (void *) (long) (ms->m_asts & AST_COMP); |
3010 | 3010 | ||
3011 | DLM_ASSERT(is_master_copy(lkb), dlm_print_lkb(lkb);); | ||
3012 | |||
3013 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { | 3011 | if (lkb->lkb_exflags & DLM_LKF_VALBLK) { |
3014 | /* lkb was just created so there won't be an lvb yet */ | 3012 | /* lkb was just created so there won't be an lvb yet */ |
3015 | lkb->lkb_lvbptr = dlm_allocate_lvb(ls); | 3013 | lkb->lkb_lvbptr = dlm_allocate_lvb(ls); |
@@ -3023,16 +3021,6 @@ static int receive_request_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
3023 | static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | 3021 | static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, |
3024 | struct dlm_message *ms) | 3022 | struct dlm_message *ms) |
3025 | { | 3023 | { |
3026 | if (lkb->lkb_nodeid != ms->m_header.h_nodeid) { | ||
3027 | log_error(ls, "convert_args nodeid %d %d lkid %x %x", | ||
3028 | lkb->lkb_nodeid, ms->m_header.h_nodeid, | ||
3029 | lkb->lkb_id, lkb->lkb_remid); | ||
3030 | return -EINVAL; | ||
3031 | } | ||
3032 | |||
3033 | if (!is_master_copy(lkb)) | ||
3034 | return -EINVAL; | ||
3035 | |||
3036 | if (lkb->lkb_status != DLM_LKSTS_GRANTED) | 3024 | if (lkb->lkb_status != DLM_LKSTS_GRANTED) |
3037 | return -EBUSY; | 3025 | return -EBUSY; |
3038 | 3026 | ||
@@ -3048,8 +3036,6 @@ static int receive_convert_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
3048 | static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | 3036 | static int receive_unlock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, |
3049 | struct dlm_message *ms) | 3037 | struct dlm_message *ms) |
3050 | { | 3038 | { |
3051 | if (!is_master_copy(lkb)) | ||
3052 | return -EINVAL; | ||
3053 | if (receive_lvb(ls, lkb, ms)) | 3039 | if (receive_lvb(ls, lkb, ms)) |
3054 | return -ENOMEM; | 3040 | return -ENOMEM; |
3055 | return 0; | 3041 | return 0; |
@@ -3065,6 +3051,50 @@ static void setup_stub_lkb(struct dlm_ls *ls, struct dlm_message *ms) | |||
3065 | lkb->lkb_remid = ms->m_lkid; | 3051 | lkb->lkb_remid = ms->m_lkid; |
3066 | } | 3052 | } |
3067 | 3053 | ||
3054 | /* This is called after the rsb is locked so that we can safely inspect | ||
3055 | fields in the lkb. */ | ||
3056 | |||
3057 | static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms) | ||
3058 | { | ||
3059 | int from = ms->m_header.h_nodeid; | ||
3060 | int error = 0; | ||
3061 | |||
3062 | switch (ms->m_type) { | ||
3063 | case DLM_MSG_CONVERT: | ||
3064 | case DLM_MSG_UNLOCK: | ||
3065 | case DLM_MSG_CANCEL: | ||
3066 | if (!is_master_copy(lkb) || lkb->lkb_nodeid != from) | ||
3067 | error = -EINVAL; | ||
3068 | break; | ||
3069 | |||
3070 | case DLM_MSG_CONVERT_REPLY: | ||
3071 | case DLM_MSG_UNLOCK_REPLY: | ||
3072 | case DLM_MSG_CANCEL_REPLY: | ||
3073 | case DLM_MSG_GRANT: | ||
3074 | case DLM_MSG_BAST: | ||
3075 | if (!is_process_copy(lkb) || lkb->lkb_nodeid != from) | ||
3076 | error = -EINVAL; | ||
3077 | break; | ||
3078 | |||
3079 | case DLM_MSG_REQUEST_REPLY: | ||
3080 | if (!is_process_copy(lkb)) | ||
3081 | error = -EINVAL; | ||
3082 | else if (lkb->lkb_nodeid != -1 && lkb->lkb_nodeid != from) | ||
3083 | error = -EINVAL; | ||
3084 | break; | ||
3085 | |||
3086 | default: | ||
3087 | error = -EINVAL; | ||
3088 | } | ||
3089 | |||
3090 | if (error) | ||
3091 | log_error(lkb->lkb_resource->res_ls, | ||
3092 | "ignore invalid message %d from %d %x %x %x %d", | ||
3093 | ms->m_type, from, lkb->lkb_id, lkb->lkb_remid, | ||
3094 | lkb->lkb_flags, lkb->lkb_nodeid); | ||
3095 | return error; | ||
3096 | } | ||
3097 | |||
3068 | static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) | 3098 | static void receive_request(struct dlm_ls *ls, struct dlm_message *ms) |
3069 | { | 3099 | { |
3070 | struct dlm_lkb *lkb; | 3100 | struct dlm_lkb *lkb; |
@@ -3126,17 +3156,21 @@ static void receive_convert(struct dlm_ls *ls, struct dlm_message *ms) | |||
3126 | hold_rsb(r); | 3156 | hold_rsb(r); |
3127 | lock_rsb(r); | 3157 | lock_rsb(r); |
3128 | 3158 | ||
3159 | error = validate_message(lkb, ms); | ||
3160 | if (error) | ||
3161 | goto out; | ||
3162 | |||
3129 | receive_flags(lkb, ms); | 3163 | receive_flags(lkb, ms); |
3130 | error = receive_convert_args(ls, lkb, ms); | 3164 | error = receive_convert_args(ls, lkb, ms); |
3131 | if (error) | 3165 | if (error) |
3132 | goto out; | 3166 | goto out_reply; |
3133 | reply = !down_conversion(lkb); | 3167 | reply = !down_conversion(lkb); |
3134 | 3168 | ||
3135 | error = do_convert(r, lkb); | 3169 | error = do_convert(r, lkb); |
3136 | out: | 3170 | out_reply: |
3137 | if (reply) | 3171 | if (reply) |
3138 | send_convert_reply(r, lkb, error); | 3172 | send_convert_reply(r, lkb, error); |
3139 | 3173 | out: | |
3140 | unlock_rsb(r); | 3174 | unlock_rsb(r); |
3141 | put_rsb(r); | 3175 | put_rsb(r); |
3142 | dlm_put_lkb(lkb); | 3176 | dlm_put_lkb(lkb); |
@@ -3162,15 +3196,19 @@ static void receive_unlock(struct dlm_ls *ls, struct dlm_message *ms) | |||
3162 | hold_rsb(r); | 3196 | hold_rsb(r); |
3163 | lock_rsb(r); | 3197 | lock_rsb(r); |
3164 | 3198 | ||
3199 | error = validate_message(lkb, ms); | ||
3200 | if (error) | ||
3201 | goto out; | ||
3202 | |||
3165 | receive_flags(lkb, ms); | 3203 | receive_flags(lkb, ms); |
3166 | error = receive_unlock_args(ls, lkb, ms); | 3204 | error = receive_unlock_args(ls, lkb, ms); |
3167 | if (error) | 3205 | if (error) |
3168 | goto out; | 3206 | goto out_reply; |
3169 | 3207 | ||
3170 | error = do_unlock(r, lkb); | 3208 | error = do_unlock(r, lkb); |
3171 | out: | 3209 | out_reply: |
3172 | send_unlock_reply(r, lkb, error); | 3210 | send_unlock_reply(r, lkb, error); |
3173 | 3211 | out: | |
3174 | unlock_rsb(r); | 3212 | unlock_rsb(r); |
3175 | put_rsb(r); | 3213 | put_rsb(r); |
3176 | dlm_put_lkb(lkb); | 3214 | dlm_put_lkb(lkb); |
@@ -3198,9 +3236,13 @@ static void receive_cancel(struct dlm_ls *ls, struct dlm_message *ms) | |||
3198 | hold_rsb(r); | 3236 | hold_rsb(r); |
3199 | lock_rsb(r); | 3237 | lock_rsb(r); |
3200 | 3238 | ||
3239 | error = validate_message(lkb, ms); | ||
3240 | if (error) | ||
3241 | goto out; | ||
3242 | |||
3201 | error = do_cancel(r, lkb); | 3243 | error = do_cancel(r, lkb); |
3202 | send_cancel_reply(r, lkb, error); | 3244 | send_cancel_reply(r, lkb, error); |
3203 | 3245 | out: | |
3204 | unlock_rsb(r); | 3246 | unlock_rsb(r); |
3205 | put_rsb(r); | 3247 | put_rsb(r); |
3206 | dlm_put_lkb(lkb); | 3248 | dlm_put_lkb(lkb); |
@@ -3219,22 +3261,26 @@ static void receive_grant(struct dlm_ls *ls, struct dlm_message *ms) | |||
3219 | 3261 | ||
3220 | error = find_lkb(ls, ms->m_remid, &lkb); | 3262 | error = find_lkb(ls, ms->m_remid, &lkb); |
3221 | if (error) { | 3263 | if (error) { |
3222 | log_error(ls, "receive_grant no lkb"); | 3264 | log_debug(ls, "receive_grant from %d no lkb %x", |
3265 | ms->m_header.h_nodeid, ms->m_remid); | ||
3223 | return; | 3266 | return; |
3224 | } | 3267 | } |
3225 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3226 | 3268 | ||
3227 | r = lkb->lkb_resource; | 3269 | r = lkb->lkb_resource; |
3228 | 3270 | ||
3229 | hold_rsb(r); | 3271 | hold_rsb(r); |
3230 | lock_rsb(r); | 3272 | lock_rsb(r); |
3231 | 3273 | ||
3274 | error = validate_message(lkb, ms); | ||
3275 | if (error) | ||
3276 | goto out; | ||
3277 | |||
3232 | receive_flags_reply(lkb, ms); | 3278 | receive_flags_reply(lkb, ms); |
3233 | if (is_altmode(lkb)) | 3279 | if (is_altmode(lkb)) |
3234 | munge_altmode(lkb, ms); | 3280 | munge_altmode(lkb, ms); |
3235 | grant_lock_pc(r, lkb, ms); | 3281 | grant_lock_pc(r, lkb, ms); |
3236 | queue_cast(r, lkb, 0); | 3282 | queue_cast(r, lkb, 0); |
3237 | 3283 | out: | |
3238 | unlock_rsb(r); | 3284 | unlock_rsb(r); |
3239 | put_rsb(r); | 3285 | put_rsb(r); |
3240 | dlm_put_lkb(lkb); | 3286 | dlm_put_lkb(lkb); |
@@ -3248,18 +3294,22 @@ static void receive_bast(struct dlm_ls *ls, struct dlm_message *ms) | |||
3248 | 3294 | ||
3249 | error = find_lkb(ls, ms->m_remid, &lkb); | 3295 | error = find_lkb(ls, ms->m_remid, &lkb); |
3250 | if (error) { | 3296 | if (error) { |
3251 | log_error(ls, "receive_bast no lkb"); | 3297 | log_debug(ls, "receive_bast from %d no lkb %x", |
3298 | ms->m_header.h_nodeid, ms->m_remid); | ||
3252 | return; | 3299 | return; |
3253 | } | 3300 | } |
3254 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3255 | 3301 | ||
3256 | r = lkb->lkb_resource; | 3302 | r = lkb->lkb_resource; |
3257 | 3303 | ||
3258 | hold_rsb(r); | 3304 | hold_rsb(r); |
3259 | lock_rsb(r); | 3305 | lock_rsb(r); |
3260 | 3306 | ||
3261 | queue_bast(r, lkb, ms->m_bastmode); | 3307 | error = validate_message(lkb, ms); |
3308 | if (error) | ||
3309 | goto out; | ||
3262 | 3310 | ||
3311 | queue_bast(r, lkb, ms->m_bastmode); | ||
3312 | out: | ||
3263 | unlock_rsb(r); | 3313 | unlock_rsb(r); |
3264 | put_rsb(r); | 3314 | put_rsb(r); |
3265 | dlm_put_lkb(lkb); | 3315 | dlm_put_lkb(lkb); |
@@ -3325,15 +3375,19 @@ static void receive_request_reply(struct dlm_ls *ls, struct dlm_message *ms) | |||
3325 | 3375 | ||
3326 | error = find_lkb(ls, ms->m_remid, &lkb); | 3376 | error = find_lkb(ls, ms->m_remid, &lkb); |
3327 | if (error) { | 3377 | if (error) { |
3328 | log_error(ls, "receive_request_reply no lkb"); | 3378 | log_debug(ls, "receive_request_reply from %d no lkb %x", |
3379 | ms->m_header.h_nodeid, ms->m_remid); | ||
3329 | return; | 3380 | return; |
3330 | } | 3381 | } |
3331 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3332 | 3382 | ||
3333 | r = lkb->lkb_resource; | 3383 | r = lkb->lkb_resource; |
3334 | hold_rsb(r); | 3384 | hold_rsb(r); |
3335 | lock_rsb(r); | 3385 | lock_rsb(r); |
3336 | 3386 | ||
3387 | error = validate_message(lkb, ms); | ||
3388 | if (error) | ||
3389 | goto out; | ||
3390 | |||
3337 | mstype = lkb->lkb_wait_type; | 3391 | mstype = lkb->lkb_wait_type; |
3338 | error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY); | 3392 | error = remove_from_waiters(lkb, DLM_MSG_REQUEST_REPLY); |
3339 | if (error) | 3393 | if (error) |
@@ -3466,6 +3520,10 @@ static void _receive_convert_reply(struct dlm_lkb *lkb, struct dlm_message *ms) | |||
3466 | hold_rsb(r); | 3520 | hold_rsb(r); |
3467 | lock_rsb(r); | 3521 | lock_rsb(r); |
3468 | 3522 | ||
3523 | error = validate_message(lkb, ms); | ||
3524 | if (error) | ||
3525 | goto out; | ||
3526 | |||
3469 | /* stub reply can happen with waiters_mutex held */ | 3527 | /* stub reply can happen with waiters_mutex held */ |
3470 | error = remove_from_waiters_ms(lkb, ms); | 3528 | error = remove_from_waiters_ms(lkb, ms); |
3471 | if (error) | 3529 | if (error) |
@@ -3484,10 +3542,10 @@ static void receive_convert_reply(struct dlm_ls *ls, struct dlm_message *ms) | |||
3484 | 3542 | ||
3485 | error = find_lkb(ls, ms->m_remid, &lkb); | 3543 | error = find_lkb(ls, ms->m_remid, &lkb); |
3486 | if (error) { | 3544 | if (error) { |
3487 | log_error(ls, "receive_convert_reply no lkb"); | 3545 | log_debug(ls, "receive_convert_reply from %d no lkb %x", |
3546 | ms->m_header.h_nodeid, ms->m_remid); | ||
3488 | return; | 3547 | return; |
3489 | } | 3548 | } |
3490 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3491 | 3549 | ||
3492 | _receive_convert_reply(lkb, ms); | 3550 | _receive_convert_reply(lkb, ms); |
3493 | dlm_put_lkb(lkb); | 3551 | dlm_put_lkb(lkb); |
@@ -3501,6 +3559,10 @@ static void _receive_unlock_reply(struct dlm_lkb *lkb, struct dlm_message *ms) | |||
3501 | hold_rsb(r); | 3559 | hold_rsb(r); |
3502 | lock_rsb(r); | 3560 | lock_rsb(r); |
3503 | 3561 | ||
3562 | error = validate_message(lkb, ms); | ||
3563 | if (error) | ||
3564 | goto out; | ||
3565 | |||
3504 | /* stub reply can happen with waiters_mutex held */ | 3566 | /* stub reply can happen with waiters_mutex held */ |
3505 | error = remove_from_waiters_ms(lkb, ms); | 3567 | error = remove_from_waiters_ms(lkb, ms); |
3506 | if (error) | 3568 | if (error) |
@@ -3532,10 +3594,10 @@ static void receive_unlock_reply(struct dlm_ls *ls, struct dlm_message *ms) | |||
3532 | 3594 | ||
3533 | error = find_lkb(ls, ms->m_remid, &lkb); | 3595 | error = find_lkb(ls, ms->m_remid, &lkb); |
3534 | if (error) { | 3596 | if (error) { |
3535 | log_error(ls, "receive_unlock_reply no lkb"); | 3597 | log_debug(ls, "receive_unlock_reply from %d no lkb %x", |
3598 | ms->m_header.h_nodeid, ms->m_remid); | ||
3536 | return; | 3599 | return; |
3537 | } | 3600 | } |
3538 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3539 | 3601 | ||
3540 | _receive_unlock_reply(lkb, ms); | 3602 | _receive_unlock_reply(lkb, ms); |
3541 | dlm_put_lkb(lkb); | 3603 | dlm_put_lkb(lkb); |
@@ -3549,6 +3611,10 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb, struct dlm_message *ms) | |||
3549 | hold_rsb(r); | 3611 | hold_rsb(r); |
3550 | lock_rsb(r); | 3612 | lock_rsb(r); |
3551 | 3613 | ||
3614 | error = validate_message(lkb, ms); | ||
3615 | if (error) | ||
3616 | goto out; | ||
3617 | |||
3552 | /* stub reply can happen with waiters_mutex held */ | 3618 | /* stub reply can happen with waiters_mutex held */ |
3553 | error = remove_from_waiters_ms(lkb, ms); | 3619 | error = remove_from_waiters_ms(lkb, ms); |
3554 | if (error) | 3620 | if (error) |
@@ -3580,10 +3646,10 @@ static void receive_cancel_reply(struct dlm_ls *ls, struct dlm_message *ms) | |||
3580 | 3646 | ||
3581 | error = find_lkb(ls, ms->m_remid, &lkb); | 3647 | error = find_lkb(ls, ms->m_remid, &lkb); |
3582 | if (error) { | 3648 | if (error) { |
3583 | log_error(ls, "receive_cancel_reply no lkb"); | 3649 | log_debug(ls, "receive_cancel_reply from %d no lkb %x", |
3650 | ms->m_header.h_nodeid, ms->m_remid); | ||
3584 | return; | 3651 | return; |
3585 | } | 3652 | } |
3586 | DLM_ASSERT(is_process_copy(lkb), dlm_print_lkb(lkb);); | ||
3587 | 3653 | ||
3588 | _receive_cancel_reply(lkb, ms); | 3654 | _receive_cancel_reply(lkb, ms); |
3589 | dlm_put_lkb(lkb); | 3655 | dlm_put_lkb(lkb); |
@@ -3816,6 +3882,7 @@ static void recover_convert_waiter(struct dlm_ls *ls, struct dlm_lkb *lkb) | |||
3816 | ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; | 3882 | ls->ls_stub_ms.m_type = DLM_MSG_CONVERT_REPLY; |
3817 | ls->ls_stub_ms.m_result = -EINPROGRESS; | 3883 | ls->ls_stub_ms.m_result = -EINPROGRESS; |
3818 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; | 3884 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; |
3885 | ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; | ||
3819 | _receive_convert_reply(lkb, &ls->ls_stub_ms); | 3886 | _receive_convert_reply(lkb, &ls->ls_stub_ms); |
3820 | 3887 | ||
3821 | /* Same special case as in receive_rcom_lock_args() */ | 3888 | /* Same special case as in receive_rcom_lock_args() */ |
@@ -3917,6 +3984,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) | |||
3917 | ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; | 3984 | ls->ls_stub_ms.m_type = DLM_MSG_UNLOCK_REPLY; |
3918 | ls->ls_stub_ms.m_result = stub_unlock_result; | 3985 | ls->ls_stub_ms.m_result = stub_unlock_result; |
3919 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; | 3986 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; |
3987 | ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; | ||
3920 | _receive_unlock_reply(lkb, &ls->ls_stub_ms); | 3988 | _receive_unlock_reply(lkb, &ls->ls_stub_ms); |
3921 | dlm_put_lkb(lkb); | 3989 | dlm_put_lkb(lkb); |
3922 | break; | 3990 | break; |
@@ -3926,6 +3994,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) | |||
3926 | ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; | 3994 | ls->ls_stub_ms.m_type = DLM_MSG_CANCEL_REPLY; |
3927 | ls->ls_stub_ms.m_result = stub_cancel_result; | 3995 | ls->ls_stub_ms.m_result = stub_cancel_result; |
3928 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; | 3996 | ls->ls_stub_ms.m_flags = lkb->lkb_flags; |
3997 | ls->ls_stub_ms.m_header.h_nodeid = lkb->lkb_nodeid; | ||
3929 | _receive_cancel_reply(lkb, &ls->ls_stub_ms); | 3998 | _receive_cancel_reply(lkb, &ls->ls_stub_ms); |
3930 | dlm_put_lkb(lkb); | 3999 | dlm_put_lkb(lkb); |
3931 | break; | 4000 | break; |