aboutsummaryrefslogtreecommitdiff
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,
if (snap_count > size / sizeof (header->snapc->snaps[0]))
return -EINVAL;
- size = sizeof (struct ceph_snap_context);
- size += snap_count * sizeof (header->snapc->snaps[0]);
- header->snapc = kmalloc(size, GFP_KERNEL);
- if (!header->snapc)
+ memset(header, 0, sizeof (*header));
+
+ size = sizeof (ondisk->block_name) + 1;
+ header->object_prefix = kmalloc(size, GFP_KERNEL);
+ if (!header->object_prefix)
return -ENOMEM;
+ memcpy(header->object_prefix, ondisk->block_name, size - 1);
+ header->object_prefix[size - 1] = '\0';
if (snap_count) {
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,
header->snap_names = kmalloc(header->snap_names_len,
GFP_KERNEL);
if (!header->snap_names)
- goto err_snapc;
+ goto out_err;
+
size = snap_count * sizeof (*header->snap_sizes);
header->snap_sizes = kmalloc(size, GFP_KERNEL);
if (!header->snap_sizes)
- goto err_names;
+ goto out_err;
} else {
WARN_ON(ondisk->snap_names_len);
header->snap_names_len = 0;
@@ -530,22 +534,23 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
header->snap_sizes = NULL;
}
- size = sizeof (ondisk->block_name) + 1;
- header->object_prefix = kmalloc(size, GFP_KERNEL);
- if (!header->object_prefix)
- goto err_sizes;
- memcpy(header->object_prefix, ondisk->block_name, size - 1);
- header->object_prefix[size - 1] = '\0';
-
header->image_size = le64_to_cpu(ondisk->image_size);
header->obj_order = ondisk->options.order;
header->crypt_type = ondisk->options.crypt_type;
header->comp_type = ondisk->options.comp_type;
+ header->total_snaps = snap_count;
+
+ /* Set up the snapshot context */
+
+ size = sizeof (struct ceph_snap_context);
+ size += snap_count * sizeof (header->snapc->snaps[0]);
+ header->snapc = kzalloc(size, GFP_KERNEL);
+ if (!header->snapc)
+ goto out_err;
atomic_set(&header->snapc->nref, 1);
header->snapc->seq = le64_to_cpu(ondisk->snap_seq);
header->snapc->num_snaps = snap_count;
- header->total_snaps = snap_count;
if (snap_count && allocated_snaps == snap_count) {
int i;
@@ -564,16 +569,14 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
return 0;
-err_sizes:
+out_err:
kfree(header->snap_sizes);
header->snap_sizes = NULL;
-err_names:
kfree(header->snap_names);
header->snap_names = NULL;
header->snap_names_len = 0;
-err_snapc:
- kfree(header->snapc);
- header->snapc = NULL;
+ kfree(header->object_prefix);
+ header->object_prefix = NULL;
return -ENOMEM;
}