rbd: look up snapshot name in names buffer
authorAlex Elder <elder@inktank.com>
Tue, 30 Apr 2013 05:44:33 +0000 (00:44 -0500)
committerSage Weil <sage@inktank.com>
Thu, 2 May 2013 04:20:18 +0000 (21:20 -0700)
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>
drivers/block/rbd.c

index 3cc080c5c49e5840c0291652b6a50684d1cfd5e6..5d1ed184bed29059549d89049c2f1a1c60163f18 100644 (file)
@@ -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);