From: Alex Elder <elder@inktank.com>
To: ceph-devel@vger.kernel.org
Subject: [PATCH 3/4] rbd: define rbd_snap_size() and rbd_snap_features()
Date: Tue, 30 Apr 2013 07:42:58 -0500 [thread overview]
Message-ID: <517FBC52.2070405@inktank.com> (raw)
In-Reply-To: <517FBBF0.9020904@inktank.com>
This patch defines a handful of new functions that will allow
us to get rid of the rbd device structure's list of snapshots.
Define rbd_snap_id_by_name() to look up a snapshot id given its
name. This is efficient for format 1 images but not for format 2.
Fortunately it only gets called at mapping time so it's not that
critical.
Use rbd_snap_id_by_name() to find out the id for a snapshot getting
mapped, and pass that id to new functions rbd_snap_size() and
rbd_snap_features() to look up information about a given snapshot's
size and feature mask given its snapshot id. All this gets done
in rbd_dev_mapping_set().
As a result, snap_by_name() is no longer needed, so get rid of it.
Signed-off-by: Alex Elder <elder@inktank.com>
---
drivers/block/rbd.c | 152
+++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 129 insertions(+), 23 deletions(-)
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index b1e1d12..67fd866d 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -435,6 +435,11 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev);
static int rbd_dev_v2_refresh(struct rbd_device *rbd_dev);
static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
u64 snap_id);
+static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
+ u8 *order, u64 *snap_size);
+static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64
snap_id,
+ u64 *snap_features);
+static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char
*name);
static int rbd_open(struct block_device *bdev, fmode_t mode)
{
@@ -840,7 +845,8 @@ static u32 rbd_dev_snap_index(struct rbd_device
*rbd_dev, u64 snap_id)
return BAD_SNAP_INDEX;
}
-static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u64
snap_id)
+static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev,
+ u64 snap_id)
{
u32 which;
@@ -863,35 +869,85 @@ static const char *rbd_snap_name(struct rbd_device
*rbd_dev, u64 snap_id)
return rbd_dev_v2_snap_name(rbd_dev, snap_id);
}
-static struct rbd_snap *snap_by_name(struct rbd_device *rbd_dev,
- const char *snap_name)
+static int rbd_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
+ u64 *snap_size)
{
- struct rbd_snap *snap;
+ rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+ if (snap_id == CEPH_NOSNAP) {
+ *snap_size = rbd_dev->header.image_size;
+ } else if (rbd_dev->image_format == 1) {
+ u32 which;
- list_for_each_entry(snap, &rbd_dev->snaps, node)
- if (!strcmp(snap_name, snap->name))
- return snap;
+ which = rbd_dev_snap_index(rbd_dev, snap_id);
+ if (which == BAD_SNAP_INDEX)
+ return -ENOENT;
- return NULL;
+ *snap_size = rbd_dev->header.snap_sizes[which];
+ } else {
+ u64 size = 0;
+ int ret;
+
+ ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size);
+ if (ret)
+ return ret;
+
+ *snap_size = size;
+ }
+ return 0;
}
-static int rbd_dev_mapping_set(struct rbd_device *rbd_dev)
+static int rbd_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
+ u64 *snap_features)
{
- if (!memcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME,
- sizeof (RBD_SNAP_HEAD_NAME))) {
- rbd_dev->mapping.size = rbd_dev->header.image_size;
- rbd_dev->mapping.features = rbd_dev->header.features;
+ rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+ if (snap_id == CEPH_NOSNAP) {
+ *snap_features = rbd_dev->header.features;
+ } else if (rbd_dev->image_format == 1) {
+ *snap_features = 0; /* No features for format 1 */
} else {
- struct rbd_snap *snap;
+ u64 features = 0;
+ int ret;
+
+ ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, &features);
+ if (ret)
+ return ret;
+
+ *snap_features = features;
+ }
+ return 0;
+}
- snap = snap_by_name(rbd_dev, rbd_dev->spec->snap_name);
- if (!snap)
+static int rbd_dev_mapping_set(struct rbd_device *rbd_dev)
+{
+ const char *snap_name = rbd_dev->spec->snap_name;
+ u64 snap_id;
+ u64 size = 0;
+ u64 features = 0;
+ int ret;
+
+ if (strcmp(snap_name, RBD_SNAP_HEAD_NAME)) {
+ snap_id = rbd_snap_id_by_name(rbd_dev, snap_name);
+ if (snap_id == CEPH_NOSNAP)
return -ENOENT;
- rbd_dev->mapping.size = snap->size;
- rbd_dev->mapping.features = snap->features;
- rbd_dev->mapping.read_only = true;
+ } else {
+ snap_id = CEPH_NOSNAP;
}
+ ret = rbd_snap_size(rbd_dev, snap_id, &size);
+ if (ret)
+ return ret;
+ ret = rbd_snap_features(rbd_dev, snap_id, &features);
+ if (ret)
+ return ret;
+
+ rbd_dev->mapping.size = size;
+ rbd_dev->mapping.features = features;
+
+ /* If we are mapping a snapshot it must be marked read-only */
+
+ if (snap_id != CEPH_NOSNAP)
+ rbd_dev->mapping.read_only = true;
+
return 0;
}
@@ -3766,6 +3822,56 @@ out:
return image_name;
}
+static u64 rbd_v1_snap_id_by_name(struct rbd_device *rbd_dev, const
char *name)
+{
+ struct ceph_snap_context *snapc = rbd_dev->header.snapc;
+ const char *snap_name;
+ u32 which = 0;
+
+ /* Skip over names until we find the one we are looking for */
+
+ snap_name = rbd_dev->header.snap_names;
+ while (which < snapc->num_snaps) {
+ if (!strcmp(name, snap_name))
+ return snapc->snaps[which];
+ snap_name += strlen(snap_name) + 1;
+ which++;
+ }
+ return CEPH_NOSNAP;
+}
+
+static u64 rbd_v2_snap_id_by_name(struct rbd_device *rbd_dev, const
char *name)
+{
+ struct ceph_snap_context *snapc = rbd_dev->header.snapc;
+ u32 which;
+ bool found = false;
+ u64 snap_id;
+
+ for (which = 0; !found && which < snapc->num_snaps; which++) {
+ const char *snap_name;
+
+ snap_id = snapc->snaps[which];
+ snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id);
+ if (IS_ERR(snap_name))
+ break;
+ found = !strcmp(name, snap_name);
+ kfree(snap_name);
+ }
+ return found ? snap_id : CEPH_NOSNAP;
+}
+
+/*
+ * Assumes name is never RBD_SNAP_HEAD_NAME; returns CEPH_NOSNAP if
+ * no snapshot by that name is found, or if an error occurs.
+ */
+static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char
*name)
+{
+ if (rbd_dev->image_format == 1)
+ return rbd_v1_snap_id_by_name(rbd_dev, name);
+
+ return rbd_v2_snap_id_by_name(rbd_dev, name);
+}
+
/*
* When an rbd image has a parent image, it is identified by the
* pool, image, and snapshot ids (not names). This function fills
@@ -3797,12 +3903,12 @@ static int rbd_dev_spec_update(struct rbd_device
*rbd_dev)
*/
if (spec->pool_name) {
if (strcmp(spec->snap_name, RBD_SNAP_HEAD_NAME)) {
- struct rbd_snap *snap;
+ u64 snap_id;
- snap = snap_by_name(rbd_dev, spec->snap_name);
- if (!snap)
+ snap_id = rbd_snap_id_by_name(rbd_dev, spec->snap_name);
+ if (snap_id == CEPH_NOSNAP)
return -ENOENT;
- spec->snap_id = snap->id;
+ spec->snap_id = snap_id;
} else {
spec->snap_id = CEPH_NOSNAP;
}
--
1.7.9.5
next prev parent reply other threads:[~2013-04-30 12:43 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-30 12:41 [PATCH 0/4] rbd: get rid of the snapshot list Alex Elder
2013-04-30 12:42 ` [PATCH 1/4] rbd: look up snapshot name in names buffer Alex Elder
2013-04-30 12:42 ` [PATCH 2/4] rbd: use snap_id not index to look up snap info Alex Elder
2013-04-30 12:42 ` Alex Elder [this message]
2013-04-30 12:43 ` [PATCH 4/4] rbd: kill off the snapshot list Alex Elder
2013-05-01 0:57 ` [PATCH 0/4] rbd: get rid of " Josh Durgin
2013-05-01 1:12 ` Alex Elder
2013-05-01 1:16 ` Alex Elder
2013-05-01 1:32 ` Josh Durgin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=517FBC52.2070405@inktank.com \
--to=elder@inktank.com \
--cc=ceph-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.