Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331683
b: refs/heads/master
c: a30b71b
h: refs/heads/master
i:
  331681: 135c604
  331679: 6106380
v: v3
  • Loading branch information
Alex Elder committed Oct 1, 2012
1 parent 1e6f333 commit 5f2977f
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cd892126c617b3837b6088bf6c097ad2def4de83
refs/heads/master: a30b71b999c92071befec73434f4e67fd4b4734b
127 changes: 99 additions & 28 deletions trunk/drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct rbd_device {
int major; /* blkdev assigned major */
struct gendisk *disk; /* blkdev's gendisk and rq */

u32 image_format; /* Either 1 or 2 */
struct rbd_options rbd_opts;
struct rbd_client *rbd_client;

Expand Down Expand Up @@ -507,6 +508,11 @@ static void rbd_coll_release(struct kref *kref)
kfree(coll);
}

static bool rbd_image_format_valid(u32 image_format)
{
return image_format == 1 || image_format == 2;
}

static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
{
size_t size;
Expand Down Expand Up @@ -2584,6 +2590,96 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev)
return ret;
}

static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
{
int ret;
size_t size;

/* Version 1 images have no id; empty string is used */

rbd_dev->image_id = kstrdup("", GFP_KERNEL);
if (!rbd_dev->image_id)
return -ENOMEM;
rbd_dev->image_id_len = 0;

/* Record the header object name for this rbd image. */

size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
if (!rbd_dev->header_name) {
ret = -ENOMEM;
goto out_err;
}
sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);

/* Populate rbd image metadata */

ret = rbd_read_header(rbd_dev, &rbd_dev->header);
if (ret < 0)
goto out_err;
rbd_dev->image_format = 1;

dout("discovered version 1 image, header name is %s\n",
rbd_dev->header_name);

return 0;

out_err:
kfree(rbd_dev->header_name);
rbd_dev->header_name = NULL;
kfree(rbd_dev->image_id);
rbd_dev->image_id = NULL;

return ret;
}

static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
{
size_t size;

/*
* Image id was filled in by the caller. Record the header
* object name for this rbd image.
*/
size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
if (!rbd_dev->header_name)
return -ENOMEM;
sprintf(rbd_dev->header_name, "%s%s",
RBD_HEADER_PREFIX, rbd_dev->image_id);
rbd_dev->image_format = 2;

dout("discovered version 2 image, header name is %s\n",
rbd_dev->header_name);

return -ENOTSUPP;
}

/*
* Probe for the existence of the header object for the given rbd
* device. For format 2 images this includes determining the image
* id.
*/
static int rbd_dev_probe(struct rbd_device *rbd_dev)
{
int ret;

/*
* Get the id from the image id object. If it's not a
* format 2 image, we'll get ENOENT back, and we'll assume
* it's a format 1 image.
*/
ret = rbd_dev_image_id(rbd_dev);
if (ret)
ret = rbd_dev_v1_probe(rbd_dev);
else
ret = rbd_dev_v2_probe(rbd_dev);
if (ret)
dout("probe failed, returning %d\n", ret);

return ret;
}

static ssize_t rbd_add(struct bus_type *bus,
const char *buf,
size_t count)
Expand Down Expand Up @@ -2631,35 +2727,10 @@ static ssize_t rbd_add(struct bus_type *bus,
goto err_out_client;
rbd_dev->pool_id = rc;

rc = rbd_dev_image_id(rbd_dev);
if (!rc) {
rc = -ENOTSUPP; /* Not actually supporting format 2 yet */
goto err_out_client;
}

/* Version 1 images have no id; empty string is used */

rbd_dev->image_id = kstrdup("", GFP_KERNEL);
if (!rbd_dev->image_id) {
rc = -ENOMEM;
goto err_out_client;
}
rbd_dev->image_id_len = 0;

/* Create the name of the header object */

rbd_dev->header_name = kmalloc(rbd_dev->image_name_len
+ sizeof (RBD_SUFFIX),
GFP_KERNEL);
if (!rbd_dev->header_name)
goto err_out_client;
sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);

/* Get information about the image being mapped */

rc = rbd_read_header(rbd_dev, &rbd_dev->header);
if (rc)
rc = rbd_dev_probe(rbd_dev);
if (rc < 0)
goto err_out_client;
rbd_assert(rbd_image_format_valid(rbd_dev->image_format));

/* no need to lock here, as rbd_dev is not registered yet */
rc = rbd_dev_snaps_update(rbd_dev);
Expand Down

0 comments on commit 5f2977f

Please sign in to comment.