diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2014-06-07 02:08:29 -0400 |
---|---|---|
committer | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2015-02-23 10:59:06 -0500 |
commit | 4664680c389828928efc61ce3d2cf2c65ad35c97 (patch) | |
tree | 9a1b976007b7047fff44a15964e32fedcd7ad935 | |
parent | 4b26a08af92c0d9c0bce07612b56ff326112321a (diff) |
Communication Framework: Receiving
1. receive status
sender receiver receiver
ACK:CR ACK:CR ACK:CR
2. sender get EX of TOKEN
sender get EX of MESSAGE
sender receiver receiver
TOKEN:EX ACK:CR ACK:CR
MESSAGE:EX
ACK:CR
3. sender write LVB.
sender down-convert MESSAGE from EX to CR
sender try to get EX of ACK
[ wait until all receiver has *processed* the MESSAGE ]
[ triggered by bast of ACK ]
receiver get CR of MESSAGE
receiver read LVB
receiver processes the message
[ wait finish ]
receiver release ACK
sender receiver receiver
TOKEN:EX MESSAGE:CR MESSAGE:CR
MESSAGE:CR
ACK:EX
4. sender down-convert ACK from EX to CR
sender release MESSAGE
sender release TOKEN
receiver upconvert to EX of MESSAGE
receiver get CR of ACK
receiver release MESSAGE
sender receiver receiver
ACK:CR ACK:CR ACK:CR
Signed-off-by: Lidong Zhong <lzhong@suse.com>
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-rw-r--r-- | drivers/md/md-cluster.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index d2987130be34..96734cdb9b45 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
@@ -52,6 +52,23 @@ struct md_cluster_info { | |||
52 | spinlock_t suspend_lock; | 52 | spinlock_t suspend_lock; |
53 | struct md_thread *recovery_thread; | 53 | struct md_thread *recovery_thread; |
54 | unsigned long recovery_map; | 54 | unsigned long recovery_map; |
55 | /* communication loc resources */ | ||
56 | struct dlm_lock_resource *ack_lockres; | ||
57 | struct dlm_lock_resource *message_lockres; | ||
58 | struct dlm_lock_resource *token_lockres; | ||
59 | struct md_thread *recv_thread; | ||
60 | }; | ||
61 | |||
62 | enum msg_type { | ||
63 | METADATA_UPDATED = 0, | ||
64 | RESYNCING, | ||
65 | }; | ||
66 | |||
67 | struct cluster_msg { | ||
68 | int type; | ||
69 | int slot; | ||
70 | sector_t low; | ||
71 | sector_t high; | ||
55 | }; | 72 | }; |
56 | 73 | ||
57 | static void sync_ast(void *arg) | 74 | static void sync_ast(void *arg) |
@@ -283,6 +300,64 @@ static const struct dlm_lockspace_ops md_ls_ops = { | |||
283 | .recover_done = recover_done, | 300 | .recover_done = recover_done, |
284 | }; | 301 | }; |
285 | 302 | ||
303 | /* | ||
304 | * The BAST function for the ack lock resource | ||
305 | * This function wakes up the receive thread in | ||
306 | * order to receive and process the message. | ||
307 | */ | ||
308 | static void ack_bast(void *arg, int mode) | ||
309 | { | ||
310 | struct dlm_lock_resource *res = (struct dlm_lock_resource *)arg; | ||
311 | struct md_cluster_info *cinfo = res->mddev->cluster_info; | ||
312 | |||
313 | if (mode == DLM_LOCK_EX) | ||
314 | md_wakeup_thread(cinfo->recv_thread); | ||
315 | } | ||
316 | |||
317 | static void process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg) | ||
318 | { | ||
319 | switch (msg->type) { | ||
320 | case METADATA_UPDATED: | ||
321 | pr_info("%s: %d Received message: METADATA_UPDATE from %d\n", | ||
322 | __func__, __LINE__, msg->slot); | ||
323 | break; | ||
324 | case RESYNCING: | ||
325 | pr_info("%s: %d Received message: RESYNCING from %d\n", | ||
326 | __func__, __LINE__, msg->slot); | ||
327 | break; | ||
328 | }; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * thread for receiving message | ||
333 | */ | ||
334 | static void recv_daemon(struct md_thread *thread) | ||
335 | { | ||
336 | struct md_cluster_info *cinfo = thread->mddev->cluster_info; | ||
337 | struct dlm_lock_resource *ack_lockres = cinfo->ack_lockres; | ||
338 | struct dlm_lock_resource *message_lockres = cinfo->message_lockres; | ||
339 | struct cluster_msg msg; | ||
340 | |||
341 | /*get CR on Message*/ | ||
342 | if (dlm_lock_sync(message_lockres, DLM_LOCK_CR)) { | ||
343 | pr_err("md/raid1:failed to get CR on MESSAGE\n"); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | /* read lvb and wake up thread to process this message_lockres */ | ||
348 | memcpy(&msg, message_lockres->lksb.sb_lvbptr, sizeof(struct cluster_msg)); | ||
349 | process_recvd_msg(thread->mddev, &msg); | ||
350 | |||
351 | /*release CR on ack_lockres*/ | ||
352 | dlm_unlock_sync(ack_lockres); | ||
353 | /*up-convert to EX on message_lockres*/ | ||
354 | dlm_lock_sync(message_lockres, DLM_LOCK_EX); | ||
355 | /*get CR on ack_lockres again*/ | ||
356 | dlm_lock_sync(ack_lockres, DLM_LOCK_CR); | ||
357 | /*release CR on message_lockres*/ | ||
358 | dlm_unlock_sync(message_lockres); | ||
359 | } | ||
360 | |||
286 | static int gather_all_resync_info(struct mddev *mddev, int total_slots) | 361 | static int gather_all_resync_info(struct mddev *mddev, int total_slots) |
287 | { | 362 | { |
288 | struct md_cluster_info *cinfo = mddev->cluster_info; | 363 | struct md_cluster_info *cinfo = mddev->cluster_info; |
@@ -368,6 +443,26 @@ static int join(struct mddev *mddev, int nodes) | |||
368 | ret = -ENOMEM; | 443 | ret = -ENOMEM; |
369 | goto err; | 444 | goto err; |
370 | } | 445 | } |
446 | /* Initiate the communication resources */ | ||
447 | ret = -ENOMEM; | ||
448 | cinfo->recv_thread = md_register_thread(recv_daemon, mddev, "cluster_recv"); | ||
449 | if (!cinfo->recv_thread) { | ||
450 | pr_err("md-cluster: cannot allocate memory for recv_thread!\n"); | ||
451 | goto err; | ||
452 | } | ||
453 | cinfo->message_lockres = lockres_init(mddev, "message", NULL, 1); | ||
454 | if (!cinfo->message_lockres) | ||
455 | goto err; | ||
456 | cinfo->token_lockres = lockres_init(mddev, "token", NULL, 0); | ||
457 | if (!cinfo->token_lockres) | ||
458 | goto err; | ||
459 | cinfo->ack_lockres = lockres_init(mddev, "ack", ack_bast, 0); | ||
460 | if (!cinfo->ack_lockres) | ||
461 | goto err; | ||
462 | /* get sync CR lock on ACK. */ | ||
463 | if (dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR)) | ||
464 | pr_err("md-cluster: failed to get a sync CR lock on ACK!(%d)\n", | ||
465 | ret); | ||
371 | 466 | ||
372 | pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); | 467 | pr_info("md-cluster: Joined cluster %s slot %d\n", str, cinfo->slot_number); |
373 | snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); | 468 | snprintf(str, 64, "bitmap%04d", cinfo->slot_number - 1); |
@@ -389,6 +484,9 @@ static int join(struct mddev *mddev, int nodes) | |||
389 | 484 | ||
390 | return 0; | 485 | return 0; |
391 | err: | 486 | err: |
487 | lockres_free(cinfo->message_lockres); | ||
488 | lockres_free(cinfo->token_lockres); | ||
489 | lockres_free(cinfo->ack_lockres); | ||
392 | lockres_free(cinfo->bitmap_lockres); | 490 | lockres_free(cinfo->bitmap_lockres); |
393 | lockres_free(cinfo->sb_lock); | 491 | lockres_free(cinfo->sb_lock); |
394 | if (cinfo->lockspace) | 492 | if (cinfo->lockspace) |
@@ -406,6 +504,10 @@ static int leave(struct mddev *mddev) | |||
406 | if (!cinfo) | 504 | if (!cinfo) |
407 | return 0; | 505 | return 0; |
408 | md_unregister_thread(&cinfo->recovery_thread); | 506 | md_unregister_thread(&cinfo->recovery_thread); |
507 | md_unregister_thread(&cinfo->recv_thread); | ||
508 | lockres_free(cinfo->message_lockres); | ||
509 | lockres_free(cinfo->token_lockres); | ||
510 | lockres_free(cinfo->ack_lockres); | ||
409 | lockres_free(cinfo->sb_lock); | 511 | lockres_free(cinfo->sb_lock); |
410 | lockres_free(cinfo->bitmap_lockres); | 512 | lockres_free(cinfo->bitmap_lockres); |
411 | dlm_release_lockspace(cinfo->lockspace, 2); | 513 | dlm_release_lockspace(cinfo->lockspace, 2); |