aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGoldwyn Rodrigues <rgoldwyn@suse.com>2014-06-07 02:08:29 -0400
committerGoldwyn Rodrigues <rgoldwyn@suse.com>2015-02-23 10:59:06 -0500
commit4664680c389828928efc61ce3d2cf2c65ad35c97 (patch)
tree9a1b976007b7047fff44a15964e32fedcd7ad935
parent4b26a08af92c0d9c0bce07612b56ff326112321a (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.c102
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
62enum msg_type {
63 METADATA_UPDATED = 0,
64 RESYNCING,
65};
66
67struct cluster_msg {
68 int type;
69 int slot;
70 sector_t low;
71 sector_t high;
55}; 72};
56 73
57static void sync_ast(void *arg) 74static 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 */
308static 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
317static 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 */
334static 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
286static int gather_all_resync_info(struct mddev *mddev, int total_slots) 361static 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;
391err: 486err:
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);