aboutsummaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-30 00:44:33 -0500
committerSage Weil <sage@inktank.com>2013-05-01 21:20:18 -0700
commit9682fc6d3a8b63f58fbfc5084f32c038170cfd6b (patch)
treec576e1c355153e7537011867ed043d83fccdaed5 /drivers/block
parentdedc81ea8468fd29bdd13eb5a362cab96b53d802 (diff)
rbd: look up snapshot name in names buffer
Rather than scanning the list of snapshot structures for it, scan the snapshot context buffer containing snapshot names in order to determine for a format 1 image the name associated with a given snapshot id. Pull out the part of rbd_dev_v1_snap_info() that does this scan into a new function, _rbd_dev_v1_snap_name(). Have that function return a dynamically-allocated copy of the name, and don't duplicate it in rbd_dev_v1_snap_info(). 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.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 3cc080c5c49..5d1ed184bed 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -66,6 +66,8 @@
#define RBD_SNAP_HEAD_NAME "-"
+#define BAD_SNAP_INDEX U32_MAX /* invalid index into snap array */
+
/* This allows a single page to hold an image name sent by OSD */
#define RBD_IMAGE_NAME_LEN_MAX (PAGE_SIZE - sizeof (__le32) - 1)
#define RBD_IMAGE_ID_LEN_MAX 64
@@ -809,6 +811,33 @@ out_err:
return -ENOMEM;
}
+static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which)
+{
+ const char *snap_name;
+
+ rbd_assert(which < rbd_dev->header.snapc->num_snaps);
+
+ /* Skip over names until we find the one we are looking for */
+
+ snap_name = rbd_dev->header.snap_names;
+ while (which--)
+ snap_name += strlen(snap_name) + 1;
+
+ return kstrdup(snap_name, GFP_KERNEL);
+}
+
+static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id)
+{
+ struct ceph_snap_context *snapc = rbd_dev->header.snapc;
+ u32 which;
+
+ for (which = 0; which < snapc->num_snaps; which++)
+ if (snapc->snaps[which] == snap_id)
+ return which;
+
+ return BAD_SNAP_INDEX;
+}
+
static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
{
struct rbd_snap *snap;
@@ -3421,17 +3450,8 @@ static const char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which,
u64 *snap_size, u64 *snap_features)
{
const char *snap_name;
- int i;
-
- rbd_assert(which < rbd_dev->header.snapc->num_snaps);
-
- /* Skip over names until we find the one we are looking for */
- snap_name = rbd_dev->header.snap_names;
- for (i = 0; i < which; i++)
- snap_name += strlen(snap_name) + 1;
-
- snap_name = kstrdup(snap_name, GFP_KERNEL);
+ snap_name = _rbd_dev_v1_snap_name(rbd_dev, which);
if (!snap_name)
return ERR_PTR(-ENOMEM);