aboutsummaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-07-19 17:12:59 -0500
committerAlex Elder <elder@inktank.com>2012-10-01 14:30:48 -0500
commit6a52325f61760c6a7d7f3ea9736029bc9f63e7f3 (patch)
tree20a3c1c9b7a37e3266db0b8532fbeabf5ed42ab6 /drivers/block
parentd2bb24e506596ad0c10e4a7f4b2fca88cc75c0bc (diff)
rbd: rearrange rbd_header_from_disk()
This just moves code around for the most part. It was pulled out as a separate patch to avoid cluttering up some upcoming patches which are more substantive. The point is basically to group everything related to initializing the snapshot context together. The only functional change is that rbd_header_from_disk() now ensures the (in-core) header it is passed is zero-filled. This allows a simpler error handling path in rbd_header_from_disk(). Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block')
-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 2a94f8e81f6..c9de0f8e808 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;
}