Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347598
b: refs/heads/master
c: 9e15b77
h: refs/heads/master
v: v3
  • Loading branch information
Alex Elder committed Nov 1, 2012
1 parent 2fde4a3 commit a033c73
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 72afc71ffca0f444ee0e1ef8c7e34ab209bb48b3
refs/heads/master: 9e15b77d9af3b63dfbff14e695336dfca88c22b2
133 changes: 133 additions & 0 deletions trunk/drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@

#define RBD_SNAP_HEAD_NAME "-"

/* 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

#define RBD_OBJ_PREFIX_LEN_MAX 64

/* Feature bits */
Expand Down Expand Up @@ -658,6 +661,20 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
return -ENOMEM;
}

static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
{
struct rbd_snap *snap;

if (snap_id == CEPH_NOSNAP)
return RBD_SNAP_HEAD_NAME;

list_for_each_entry(snap, &rbd_dev->snaps, node)
if (snap_id == snap->id)
return snap->name;

return NULL;
}

static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name)
{

Expand Down Expand Up @@ -2499,6 +2516,7 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
goto out_err;
}
parent_spec->image_id = image_id;
parent_spec->image_id_len = len;
ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err);
ceph_decode_64_safe(&p, end, overlap, out_err);

Expand All @@ -2514,6 +2532,117 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
return ret;
}

static char *rbd_dev_image_name(struct rbd_device *rbd_dev)
{
size_t image_id_size;
char *image_id;
void *p;
void *end;
size_t size;
void *reply_buf = NULL;
size_t len = 0;
char *image_name = NULL;
int ret;

rbd_assert(!rbd_dev->spec->image_name);

image_id_size = sizeof (__le32) + rbd_dev->spec->image_id_len;
image_id = kmalloc(image_id_size, GFP_KERNEL);
if (!image_id)
return NULL;

p = image_id;
end = (char *) image_id + image_id_size;
ceph_encode_string(&p, end, rbd_dev->spec->image_id,
(u32) rbd_dev->spec->image_id_len);

size = sizeof (__le32) + RBD_IMAGE_NAME_LEN_MAX;
reply_buf = kmalloc(size, GFP_KERNEL);
if (!reply_buf)
goto out;

ret = rbd_req_sync_exec(rbd_dev, RBD_DIRECTORY,
"rbd", "dir_get_name",
image_id, image_id_size,
(char *) reply_buf, size,
CEPH_OSD_FLAG_READ, NULL);
if (ret < 0)
goto out;
p = reply_buf;
end = (char *) reply_buf + size;
image_name = ceph_extract_encoded_string(&p, end, &len, GFP_KERNEL);
if (IS_ERR(image_name))
image_name = NULL;
else
dout("%s: name is %s len is %zd\n", __func__, image_name, len);
out:
kfree(reply_buf);
kfree(image_id);

return image_name;
}

/*
* When a parent image gets probed, we only have the pool, image,
* and snapshot ids but not the names of any of them. This call
* is made later to fill in those names. It has to be done after
* rbd_dev_snaps_update() has completed because some of the
* information (in particular, snapshot name) is not available
* until then.
*/
static int rbd_dev_probe_update_spec(struct rbd_device *rbd_dev)
{
struct ceph_osd_client *osdc;
const char *name;
void *reply_buf = NULL;
int ret;

if (rbd_dev->spec->pool_name)
return 0; /* Already have the names */

/* Look up the pool name */

osdc = &rbd_dev->rbd_client->client->osdc;
name = ceph_pg_pool_name_by_id(osdc->osdmap, rbd_dev->spec->pool_id);
if (!name)
return -EIO; /* pool id too large (>= 2^31) */

rbd_dev->spec->pool_name = kstrdup(name, GFP_KERNEL);
if (!rbd_dev->spec->pool_name)
return -ENOMEM;

/* Fetch the image name; tolerate failure here */

name = rbd_dev_image_name(rbd_dev);
if (name) {
rbd_dev->spec->image_name_len = strlen(name);
rbd_dev->spec->image_name = (char *) name;
} else {
pr_warning(RBD_DRV_NAME "%d "
"unable to get image name for image id %s\n",
rbd_dev->major, rbd_dev->spec->image_id);
}

/* Look up the snapshot name. */

name = rbd_snap_name(rbd_dev, rbd_dev->spec->snap_id);
if (!name) {
ret = -EIO;
goto out_err;
}
rbd_dev->spec->snap_name = kstrdup(name, GFP_KERNEL);
if(!rbd_dev->spec->snap_name)
goto out_err;

return 0;
out_err:
kfree(reply_buf);
kfree(rbd_dev->spec->pool_name);
rbd_dev->spec->pool_name = NULL;

return ret;
}

static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver)
{
size_t size;
Expand Down Expand Up @@ -3372,6 +3501,10 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
if (ret)
return ret;

ret = rbd_dev_probe_update_spec(rbd_dev);
if (ret)
goto err_out_snaps;

ret = rbd_dev_set_mapping(rbd_dev);
if (ret)
goto err_out_snaps;
Expand Down

0 comments on commit a033c73

Please sign in to comment.