diff options
author | Alex Elder <elder@inktank.com> | 2013-04-30 09:44:33 +0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 08:20:18 +0400 |
commit | 9682fc6d3a8b63f58fbfc5084f32c038170cfd6b (patch) | |
tree | c576e1c355153e7537011867ed043d83fccdaed5 /drivers/block | |
parent | dedc81ea8468fd29bdd13eb5a362cab96b53d802 (diff) | |
download | linux-9682fc6d3a8b63f58fbfc5084f32c038170cfd6b.tar.xz |
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.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 3cc080c5c49e..5d1ed184bed2 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); |