diff options
-rw-r--r-- | drivers/block/rbd.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 2a94f8e81f67..c9de0f8e808e 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -506,11 +506,14 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
506 | if (snap_count > size / sizeof (header->snapc->snaps[0])) | 506 | if (snap_count > size / sizeof (header->snapc->snaps[0])) |
507 | return -EINVAL; | 507 | return -EINVAL; |
508 | 508 | ||
509 | size = sizeof (struct ceph_snap_context); | 509 | memset(header, 0, sizeof (*header)); |
510 | size += snap_count * sizeof (header->snapc->snaps[0]); | 510 | |
511 | header->snapc = kmalloc(size, GFP_KERNEL); | 511 | size = sizeof (ondisk->block_name) + 1; |
512 | if (!header->snapc) | 512 | header->object_prefix = kmalloc(size, GFP_KERNEL); |
513 | if (!header->object_prefix) | ||
513 | return -ENOMEM; | 514 | return -ENOMEM; |
515 | memcpy(header->object_prefix, ondisk->block_name, size - 1); | ||
516 | header->object_prefix[size - 1] = '\0'; | ||
514 | 517 | ||
515 | if (snap_count) { | 518 | if (snap_count) { |
516 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); | 519 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); |
@@ -518,11 +521,12 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
518 | header->snap_names = kmalloc(header->snap_names_len, | 521 | header->snap_names = kmalloc(header->snap_names_len, |
519 | GFP_KERNEL); | 522 | GFP_KERNEL); |
520 | if (!header->snap_names) | 523 | if (!header->snap_names) |
521 | goto err_snapc; | 524 | goto out_err; |
525 | |||
522 | size = snap_count * sizeof (*header->snap_sizes); | 526 | size = snap_count * sizeof (*header->snap_sizes); |
523 | header->snap_sizes = kmalloc(size, GFP_KERNEL); | 527 | header->snap_sizes = kmalloc(size, GFP_KERNEL); |
524 | if (!header->snap_sizes) | 528 | if (!header->snap_sizes) |
525 | goto err_names; | 529 | goto out_err; |
526 | } else { | 530 | } else { |
527 | WARN_ON(ondisk->snap_names_len); | 531 | WARN_ON(ondisk->snap_names_len); |
528 | header->snap_names_len = 0; | 532 | header->snap_names_len = 0; |
@@ -530,22 +534,23 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
530 | header->snap_sizes = NULL; | 534 | header->snap_sizes = NULL; |
531 | } | 535 | } |
532 | 536 | ||
533 | size = sizeof (ondisk->block_name) + 1; | ||
534 | header->object_prefix = kmalloc(size, GFP_KERNEL); | ||
535 | if (!header->object_prefix) | ||
536 | goto err_sizes; | ||
537 | memcpy(header->object_prefix, ondisk->block_name, size - 1); | ||
538 | header->object_prefix[size - 1] = '\0'; | ||
539 | |||
540 | header->image_size = le64_to_cpu(ondisk->image_size); | 537 | header->image_size = le64_to_cpu(ondisk->image_size); |
541 | header->obj_order = ondisk->options.order; | 538 | header->obj_order = ondisk->options.order; |
542 | header->crypt_type = ondisk->options.crypt_type; | 539 | header->crypt_type = ondisk->options.crypt_type; |
543 | header->comp_type = ondisk->options.comp_type; | 540 | header->comp_type = ondisk->options.comp_type; |
541 | header->total_snaps = snap_count; | ||
542 | |||
543 | /* Set up the snapshot context */ | ||
544 | |||
545 | size = sizeof (struct ceph_snap_context); | ||
546 | size += snap_count * sizeof (header->snapc->snaps[0]); | ||
547 | header->snapc = kzalloc(size, GFP_KERNEL); | ||
548 | if (!header->snapc) | ||
549 | goto out_err; | ||
544 | 550 | ||
545 | atomic_set(&header->snapc->nref, 1); | 551 | atomic_set(&header->snapc->nref, 1); |
546 | header->snapc->seq = le64_to_cpu(ondisk->snap_seq); | 552 | header->snapc->seq = le64_to_cpu(ondisk->snap_seq); |
547 | header->snapc->num_snaps = snap_count; | 553 | header->snapc->num_snaps = snap_count; |
548 | header->total_snaps = snap_count; | ||
549 | 554 | ||
550 | if (snap_count && allocated_snaps == snap_count) { | 555 | if (snap_count && allocated_snaps == snap_count) { |
551 | int i; | 556 | int i; |
@@ -564,16 +569,14 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
564 | 569 | ||
565 | return 0; | 570 | return 0; |
566 | 571 | ||
567 | err_sizes: | 572 | out_err: |
568 | kfree(header->snap_sizes); | 573 | kfree(header->snap_sizes); |
569 | header->snap_sizes = NULL; | 574 | header->snap_sizes = NULL; |
570 | err_names: | ||
571 | kfree(header->snap_names); | 575 | kfree(header->snap_names); |
572 | header->snap_names = NULL; | 576 | header->snap_names = NULL; |
573 | header->snap_names_len = 0; | 577 | header->snap_names_len = 0; |
574 | err_snapc: | 578 | kfree(header->object_prefix); |
575 | kfree(header->snapc); | 579 | header->object_prefix = NULL; |
576 | header->snapc = NULL; | ||
577 | 580 | ||
578 | return -ENOMEM; | 581 | return -ENOMEM; |
579 | } | 582 | } |