aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-10-30 20:40:33 -0400
committerAlex Elder <elder@inktank.com>2012-11-01 08:55:42 -0400
commit9e15b77d9af3b63dfbff14e695336dfca88c22b2 (patch)
tree009f652ab8c5a8d909c9cf1994d30b5a2e30ef0d /drivers/block
parent72afc71ffca0f444ee0e1ef8c7e34ab209bb48b3 (diff)
rbd: get additional info in parent spec
When a layered rbd image has a parent, that parent is identified only by its pool id, image id, and snapshot id. Images that have been mapped also record *names* for those three id's. Add code to look up these names for parent images so they match mapped images more closely. Skip doing this for an image if it already has its pool name defined (this will be the case for images mapped by the user). It is possible that an the name of a parent image can't be determined, even if the image id is valid. If this occurs it does not preclude correct operation, so don't treat this as an error. On the other hand, defined pools will always have both an id and a name. And any snapshot of an image identified as a parent for a clone image will exist, and will have a name (if not it indicates some other internal error). So treat failure to get these bits of information as errors. 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.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index bce1fcfb5185..842caf4aab47 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -70,7 +70,10 @@
70 70
71#define RBD_SNAP_HEAD_NAME "-" 71#define RBD_SNAP_HEAD_NAME "-"
72 72
73/* This allows a single page to hold an image name sent by OSD */
74#define RBD_IMAGE_NAME_LEN_MAX (PAGE_SIZE - sizeof (__le32) - 1)
73#define RBD_IMAGE_ID_LEN_MAX 64 75#define RBD_IMAGE_ID_LEN_MAX 64
76
74#define RBD_OBJ_PREFIX_LEN_MAX 64 77#define RBD_OBJ_PREFIX_LEN_MAX 64
75 78
76/* Feature bits */ 79/* Feature bits */
@@ -658,6 +661,20 @@ out_err:
658 return -ENOMEM; 661 return -ENOMEM;
659} 662}
660 663
664static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id)
665{
666 struct rbd_snap *snap;
667
668 if (snap_id == CEPH_NOSNAP)
669 return RBD_SNAP_HEAD_NAME;
670
671 list_for_each_entry(snap, &rbd_dev->snaps, node)
672 if (snap_id == snap->id)
673 return snap->name;
674
675 return NULL;
676}
677
661static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name) 678static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name)
662{ 679{
663 680
@@ -2499,6 +2516,7 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)
2499 goto out_err; 2516 goto out_err;
2500 } 2517 }
2501 parent_spec->image_id = image_id; 2518 parent_spec->image_id = image_id;
2519 parent_spec->image_id_len = len;
2502 ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err); 2520 ceph_decode_64_safe(&p, end, parent_spec->snap_id, out_err);
2503 ceph_decode_64_safe(&p, end, overlap, out_err); 2521 ceph_decode_64_safe(&p, end, overlap, out_err);
2504 2522
@@ -2514,6 +2532,117 @@ out_err:
2514 return ret; 2532 return ret;
2515} 2533}
2516 2534
2535static char *rbd_dev_image_name(struct rbd_device *rbd_dev)
2536{
2537 size_t image_id_size;
2538 char *image_id;
2539 void *p;
2540 void *end;
2541 size_t size;
2542 void *reply_buf = NULL;
2543 size_t len = 0;
2544 char *image_name = NULL;
2545 int ret;
2546
2547 rbd_assert(!rbd_dev->spec->image_name);
2548
2549 image_id_size = sizeof (__le32) + rbd_dev->spec->image_id_len;
2550 image_id = kmalloc(image_id_size, GFP_KERNEL);
2551 if (!image_id)
2552 return NULL;
2553
2554 p = image_id;
2555 end = (char *) image_id + image_id_size;
2556 ceph_encode_string(&p, end, rbd_dev->spec->image_id,
2557 (u32) rbd_dev->spec->image_id_len);
2558
2559 size = sizeof (__le32) + RBD_IMAGE_NAME_LEN_MAX;
2560 reply_buf = kmalloc(size, GFP_KERNEL);
2561 if (!reply_buf)
2562 goto out;
2563
2564 ret = rbd_req_sync_exec(rbd_dev, RBD_DIRECTORY,
2565 "rbd", "dir_get_name",
2566 image_id, image_id_size,
2567 (char *) reply_buf, size,
2568 CEPH_OSD_FLAG_READ, NULL);
2569 if (ret < 0)
2570 goto out;
2571 p = reply_buf;
2572 end = (char *) reply_buf + size;
2573 image_name = ceph_extract_encoded_string(&p, end, &len, GFP_KERNEL);
2574 if (IS_ERR(image_name))
2575 image_name = NULL;
2576 else
2577 dout("%s: name is %s len is %zd\n", __func__, image_name, len);
2578out:
2579 kfree(reply_buf);
2580 kfree(image_id);
2581
2582 return image_name;
2583}
2584
2585/*
2586 * When a parent image gets probed, we only have the pool, image,
2587 * and snapshot ids but not the names of any of them. This call
2588 * is made later to fill in those names. It has to be done after
2589 * rbd_dev_snaps_update() has completed because some of the
2590 * information (in particular, snapshot name) is not available
2591 * until then.
2592 */
2593static int rbd_dev_probe_update_spec(struct rbd_device *rbd_dev)
2594{
2595 struct ceph_osd_client *osdc;
2596 const char *name;
2597 void *reply_buf = NULL;
2598 int ret;
2599
2600 if (rbd_dev->spec->pool_name)
2601 return 0; /* Already have the names */
2602
2603 /* Look up the pool name */
2604
2605 osdc = &rbd_dev->rbd_client->client->osdc;
2606 name = ceph_pg_pool_name_by_id(osdc->osdmap, rbd_dev->spec->pool_id);
2607 if (!name)
2608 return -EIO; /* pool id too large (>= 2^31) */
2609
2610 rbd_dev->spec->pool_name = kstrdup(name, GFP_KERNEL);
2611 if (!rbd_dev->spec->pool_name)
2612 return -ENOMEM;
2613
2614 /* Fetch the image name; tolerate failure here */
2615
2616 name = rbd_dev_image_name(rbd_dev);
2617 if (name) {
2618 rbd_dev->spec->image_name_len = strlen(name);
2619 rbd_dev->spec->image_name = (char *) name;
2620 } else {
2621 pr_warning(RBD_DRV_NAME "%d "
2622 "unable to get image name for image id %s\n",
2623 rbd_dev->major, rbd_dev->spec->image_id);
2624 }
2625
2626 /* Look up the snapshot name. */
2627
2628 name = rbd_snap_name(rbd_dev, rbd_dev->spec->snap_id);
2629 if (!name) {
2630 ret = -EIO;
2631 goto out_err;
2632 }
2633 rbd_dev->spec->snap_name = kstrdup(name, GFP_KERNEL);
2634 if(!rbd_dev->spec->snap_name)
2635 goto out_err;
2636
2637 return 0;
2638out_err:
2639 kfree(reply_buf);
2640 kfree(rbd_dev->spec->pool_name);
2641 rbd_dev->spec->pool_name = NULL;
2642
2643 return ret;
2644}
2645
2517static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver) 2646static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver)
2518{ 2647{
2519 size_t size; 2648 size_t size;
@@ -3372,6 +3501,10 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
3372 if (ret) 3501 if (ret)
3373 return ret; 3502 return ret;
3374 3503
3504 ret = rbd_dev_probe_update_spec(rbd_dev);
3505 if (ret)
3506 goto err_out_snaps;
3507
3375 ret = rbd_dev_set_mapping(rbd_dev); 3508 ret = rbd_dev_set_mapping(rbd_dev);
3376 if (ret) 3509 if (ret)
3377 goto err_out_snaps; 3510 goto err_out_snaps;