aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2012-07-10 21:30:11 -0400
committerAlex Elder <elder@inktank.com>2012-10-01 15:30:53 -0400
commita30b71b999c92071befec73434f4e67fd4b4734b (patch)
treefc48430344eb6904fa59c9f7a2a121add329ebba /drivers/block
parentcd892126c617b3837b6088bf6c097ad2def4de83 (diff)
rbd: lay out header probe infrastructure
This defines a new function rbd_dev_probe() as a top-level function for populating detailed information about an rbd device. It first checks for the existence of a format 2 rbd image id object. If it exists, the image is assumed to be a format 2 rbd image, and another function rbd_dev_v2() is called to finish populating header data for that image. If it does not exist, it is assumed to be an old (format 1) rbd image, and calls a similar function rbd_dev_v1() to populate its header information. A new field, rbd_dev->format, is defined to record which version of the rbd image format the device represents. For a valid mapped rbd device it will have one of two values, 1 or 2. So far, the format 2 images are not really supported; this is laying out the infrastructure for fleshing out that support. 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.c127
1 files changed, 99 insertions, 28 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 366a3a1f2aac..3b284d53a566 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -170,6 +170,7 @@ struct rbd_device {
170 int major; /* blkdev assigned major */ 170 int major; /* blkdev assigned major */
171 struct gendisk *disk; /* blkdev's gendisk and rq */ 171 struct gendisk *disk; /* blkdev's gendisk and rq */
172 172
173 u32 image_format; /* Either 1 or 2 */
173 struct rbd_options rbd_opts; 174 struct rbd_options rbd_opts;
174 struct rbd_client *rbd_client; 175 struct rbd_client *rbd_client;
175 176
@@ -507,6 +508,11 @@ static void rbd_coll_release(struct kref *kref)
507 kfree(coll); 508 kfree(coll);
508} 509}
509 510
511static bool rbd_image_format_valid(u32 image_format)
512{
513 return image_format == 1 || image_format == 2;
514}
515
510static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk) 516static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
511{ 517{
512 size_t size; 518 size_t size;
@@ -2584,6 +2590,96 @@ out:
2584 return ret; 2590 return ret;
2585} 2591}
2586 2592
2593static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
2594{
2595 int ret;
2596 size_t size;
2597
2598 /* Version 1 images have no id; empty string is used */
2599
2600 rbd_dev->image_id = kstrdup("", GFP_KERNEL);
2601 if (!rbd_dev->image_id)
2602 return -ENOMEM;
2603 rbd_dev->image_id_len = 0;
2604
2605 /* Record the header object name for this rbd image. */
2606
2607 size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
2608 rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
2609 if (!rbd_dev->header_name) {
2610 ret = -ENOMEM;
2611 goto out_err;
2612 }
2613 sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
2614
2615 /* Populate rbd image metadata */
2616
2617 ret = rbd_read_header(rbd_dev, &rbd_dev->header);
2618 if (ret < 0)
2619 goto out_err;
2620 rbd_dev->image_format = 1;
2621
2622 dout("discovered version 1 image, header name is %s\n",
2623 rbd_dev->header_name);
2624
2625 return 0;
2626
2627out_err:
2628 kfree(rbd_dev->header_name);
2629 rbd_dev->header_name = NULL;
2630 kfree(rbd_dev->image_id);
2631 rbd_dev->image_id = NULL;
2632
2633 return ret;
2634}
2635
2636static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
2637{
2638 size_t size;
2639
2640 /*
2641 * Image id was filled in by the caller. Record the header
2642 * object name for this rbd image.
2643 */
2644 size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
2645 rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
2646 if (!rbd_dev->header_name)
2647 return -ENOMEM;
2648 sprintf(rbd_dev->header_name, "%s%s",
2649 RBD_HEADER_PREFIX, rbd_dev->image_id);
2650 rbd_dev->image_format = 2;
2651
2652 dout("discovered version 2 image, header name is %s\n",
2653 rbd_dev->header_name);
2654
2655 return -ENOTSUPP;
2656}
2657
2658/*
2659 * Probe for the existence of the header object for the given rbd
2660 * device. For format 2 images this includes determining the image
2661 * id.
2662 */
2663static int rbd_dev_probe(struct rbd_device *rbd_dev)
2664{
2665 int ret;
2666
2667 /*
2668 * Get the id from the image id object. If it's not a
2669 * format 2 image, we'll get ENOENT back, and we'll assume
2670 * it's a format 1 image.
2671 */
2672 ret = rbd_dev_image_id(rbd_dev);
2673 if (ret)
2674 ret = rbd_dev_v1_probe(rbd_dev);
2675 else
2676 ret = rbd_dev_v2_probe(rbd_dev);
2677 if (ret)
2678 dout("probe failed, returning %d\n", ret);
2679
2680 return ret;
2681}
2682
2587static ssize_t rbd_add(struct bus_type *bus, 2683static ssize_t rbd_add(struct bus_type *bus,
2588 const char *buf, 2684 const char *buf,
2589 size_t count) 2685 size_t count)
@@ -2631,35 +2727,10 @@ static ssize_t rbd_add(struct bus_type *bus,
2631 goto err_out_client; 2727 goto err_out_client;
2632 rbd_dev->pool_id = rc; 2728 rbd_dev->pool_id = rc;
2633 2729
2634 rc = rbd_dev_image_id(rbd_dev); 2730 rc = rbd_dev_probe(rbd_dev);
2635 if (!rc) { 2731 if (rc < 0)
2636 rc = -ENOTSUPP; /* Not actually supporting format 2 yet */
2637 goto err_out_client;
2638 }
2639
2640 /* Version 1 images have no id; empty string is used */
2641
2642 rbd_dev->image_id = kstrdup("", GFP_KERNEL);
2643 if (!rbd_dev->image_id) {
2644 rc = -ENOMEM;
2645 goto err_out_client;
2646 }
2647 rbd_dev->image_id_len = 0;
2648
2649 /* Create the name of the header object */
2650
2651 rbd_dev->header_name = kmalloc(rbd_dev->image_name_len
2652 + sizeof (RBD_SUFFIX),
2653 GFP_KERNEL);
2654 if (!rbd_dev->header_name)
2655 goto err_out_client;
2656 sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
2657
2658 /* Get information about the image being mapped */
2659
2660 rc = rbd_read_header(rbd_dev, &rbd_dev->header);
2661 if (rc)
2662 goto err_out_client; 2732 goto err_out_client;
2733 rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
2663 2734
2664 /* no need to lock here, as rbd_dev is not registered yet */ 2735 /* no need to lock here, as rbd_dev is not registered yet */
2665 rc = rbd_dev_snaps_update(rbd_dev); 2736 rc = rbd_dev_snaps_update(rbd_dev);