aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c41
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
567err_sizes: 572out_err:
568 kfree(header->snap_sizes); 573 kfree(header->snap_sizes);
569 header->snap_sizes = NULL; 574 header->snap_sizes = NULL;
570err_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;
574err_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}