diff options
author | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2014-06-07 02:28:53 -0400 |
---|---|---|
committer | Goldwyn Rodrigues <rgoldwyn@suse.com> | 2015-02-23 10:59:06 -0500 |
commit | 601b515c5dcc00fa71148cd9d2405ea1f70bc9cd (patch) | |
tree | 3f798549738830d44d83a5f8cb547266b06b83de | |
parent | 4664680c389828928efc61ce3d2cf2c65ad35c97 (diff) |
Communication Framework: Sending functions
The sending part is split in two functions to make sure
atomicity of the operations, such as the MD superblock update.
Signed-off-by: Lidong Zhong <lzhong@suse.com>
Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
-rw-r--r-- | drivers/md/md-cluster.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 96734cdb9b45..9a4abe1b4aa4 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c | |||
@@ -358,6 +358,93 @@ static void recv_daemon(struct md_thread *thread) | |||
358 | dlm_unlock_sync(message_lockres); | 358 | dlm_unlock_sync(message_lockres); |
359 | } | 359 | } |
360 | 360 | ||
361 | /* lock_comm() | ||
362 | * Takes the lock on the TOKEN lock resource so no other | ||
363 | * node can communicate while the operation is underway. | ||
364 | */ | ||
365 | static int lock_comm(struct md_cluster_info *cinfo) | ||
366 | { | ||
367 | int error; | ||
368 | |||
369 | error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX); | ||
370 | if (error) | ||
371 | pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n", | ||
372 | __func__, __LINE__, error); | ||
373 | return error; | ||
374 | } | ||
375 | |||
376 | static void unlock_comm(struct md_cluster_info *cinfo) | ||
377 | { | ||
378 | dlm_unlock_sync(cinfo->token_lockres); | ||
379 | } | ||
380 | |||
381 | /* __sendmsg() | ||
382 | * This function performs the actual sending of the message. This function is | ||
383 | * usually called after performing the encompassing operation | ||
384 | * The function: | ||
385 | * 1. Grabs the message lockresource in EX mode | ||
386 | * 2. Copies the message to the message LVB | ||
387 | * 3. Downconverts message lockresource to CR | ||
388 | * 4. Upconverts ack lock resource from CR to EX. This forces the BAST on other nodes | ||
389 | * and the other nodes read the message. The thread will wait here until all other | ||
390 | * nodes have released ack lock resource. | ||
391 | * 5. Downconvert ack lockresource to CR | ||
392 | */ | ||
393 | static int __sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg) | ||
394 | { | ||
395 | int error; | ||
396 | int slot = cinfo->slot_number - 1; | ||
397 | |||
398 | cmsg->slot = cpu_to_le32(slot); | ||
399 | /*get EX on Message*/ | ||
400 | error = dlm_lock_sync(cinfo->message_lockres, DLM_LOCK_EX); | ||
401 | if (error) { | ||
402 | pr_err("md-cluster: failed to get EX on MESSAGE (%d)\n", error); | ||
403 | goto failed_message; | ||
404 | } | ||
405 | |||
406 | memcpy(cinfo->message_lockres->lksb.sb_lvbptr, (void *)cmsg, | ||
407 | sizeof(struct cluster_msg)); | ||
408 | /*down-convert EX to CR on Message*/ | ||
409 | error = dlm_lock_sync(cinfo->message_lockres, DLM_LOCK_CR); | ||
410 | if (error) { | ||
411 | pr_err("md-cluster: failed to convert EX to CR on MESSAGE(%d)\n", | ||
412 | error); | ||
413 | goto failed_message; | ||
414 | } | ||
415 | |||
416 | /*up-convert CR to EX on Ack*/ | ||
417 | error = dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_EX); | ||
418 | if (error) { | ||
419 | pr_err("md-cluster: failed to convert CR to EX on ACK(%d)\n", | ||
420 | error); | ||
421 | goto failed_ack; | ||
422 | } | ||
423 | |||
424 | /*down-convert EX to CR on Ack*/ | ||
425 | error = dlm_lock_sync(cinfo->ack_lockres, DLM_LOCK_CR); | ||
426 | if (error) { | ||
427 | pr_err("md-cluster: failed to convert EX to CR on ACK(%d)\n", | ||
428 | error); | ||
429 | goto failed_ack; | ||
430 | } | ||
431 | |||
432 | failed_ack: | ||
433 | dlm_unlock_sync(cinfo->message_lockres); | ||
434 | failed_message: | ||
435 | return error; | ||
436 | } | ||
437 | |||
438 | static int sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg) | ||
439 | { | ||
440 | int ret; | ||
441 | |||
442 | lock_comm(cinfo); | ||
443 | ret = __sendmsg(cinfo, cmsg); | ||
444 | unlock_comm(cinfo); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
361 | static int gather_all_resync_info(struct mddev *mddev, int total_slots) | 448 | static int gather_all_resync_info(struct mddev *mddev, int total_slots) |
362 | { | 449 | { |
363 | struct md_cluster_info *cinfo = mddev->cluster_info; | 450 | struct md_cluster_info *cinfo = mddev->cluster_info; |