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
commit589d30e0b3e649e2660f9a67be88e235b28bc319 (patch)
tree7430a5eea84dc3378ba69a5cd563577afb98b228 /drivers/block
parent3bb59ad515527fa75cf71d997d17cea18160da74 (diff)
rbd: define rbd_dev_image_id()
New format 2 rbd images are permanently identified by a unique image id. Each rbd image also has a name, but the name can be changed. A format 2 rbd image will have an object--whose name is based on the image name--which maps an image's name to its image id. Create a new function rbd_dev_image_id() that checks for the existence of the image id object, and if it's found, records the image id in the rbd_device structure. Create a new rbd device attribute (/sys/bus/rbd/<num>/image_id) that makes this information available. 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.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index b8956131950c..34f46c3b188f 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -66,6 +66,8 @@
66 66
67#define RBD_SNAP_HEAD_NAME "-" 67#define RBD_SNAP_HEAD_NAME "-"
68 68
69#define RBD_IMAGE_ID_LEN_MAX 64
70
69/* 71/*
70 * An RBD device name will be "rbd#", where the "rbd" comes from 72 * An RBD device name will be "rbd#", where the "rbd" comes from
71 * RBD_DRV_NAME above, and # is a unique integer identifier. 73 * RBD_DRV_NAME above, and # is a unique integer identifier.
@@ -173,6 +175,8 @@ struct rbd_device {
173 spinlock_t lock; /* queue lock */ 175 spinlock_t lock; /* queue lock */
174 176
175 struct rbd_image_header header; 177 struct rbd_image_header header;
178 char *image_id;
179 size_t image_id_len;
176 char *image_name; 180 char *image_name;
177 size_t image_name_len; 181 size_t image_name_len;
178 char *header_name; 182 char *header_name;
@@ -1987,6 +1991,14 @@ static ssize_t rbd_name_show(struct device *dev,
1987 return sprintf(buf, "%s\n", rbd_dev->image_name); 1991 return sprintf(buf, "%s\n", rbd_dev->image_name);
1988} 1992}
1989 1993
1994static ssize_t rbd_image_id_show(struct device *dev,
1995 struct device_attribute *attr, char *buf)
1996{
1997 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
1998
1999 return sprintf(buf, "%s\n", rbd_dev->image_id);
2000}
2001
1990static ssize_t rbd_snap_show(struct device *dev, 2002static ssize_t rbd_snap_show(struct device *dev,
1991 struct device_attribute *attr, 2003 struct device_attribute *attr,
1992 char *buf) 2004 char *buf)
@@ -2015,6 +2027,7 @@ static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
2015static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL); 2027static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
2016static DEVICE_ATTR(pool_id, S_IRUGO, rbd_pool_id_show, NULL); 2028static DEVICE_ATTR(pool_id, S_IRUGO, rbd_pool_id_show, NULL);
2017static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL); 2029static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
2030static DEVICE_ATTR(image_id, S_IRUGO, rbd_image_id_show, NULL);
2018static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); 2031static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
2019static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); 2032static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
2020static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); 2033static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
@@ -2026,6 +2039,7 @@ static struct attribute *rbd_attrs[] = {
2026 &dev_attr_pool.attr, 2039 &dev_attr_pool.attr,
2027 &dev_attr_pool_id.attr, 2040 &dev_attr_pool_id.attr,
2028 &dev_attr_name.attr, 2041 &dev_attr_name.attr,
2042 &dev_attr_image_id.attr,
2029 &dev_attr_current_snap.attr, 2043 &dev_attr_current_snap.attr,
2030 &dev_attr_refresh.attr, 2044 &dev_attr_refresh.attr,
2031 &dev_attr_create_snap.attr, 2045 &dev_attr_create_snap.attr,
@@ -2553,6 +2567,75 @@ out_err:
2553 return err_ptr; 2567 return err_ptr;
2554} 2568}
2555 2569
2570/*
2571 * An rbd format 2 image has a unique identifier, distinct from the
2572 * name given to it by the user. Internally, that identifier is
2573 * what's used to specify the names of objects related to the image.
2574 *
2575 * A special "rbd id" object is used to map an rbd image name to its
2576 * id. If that object doesn't exist, then there is no v2 rbd image
2577 * with the supplied name.
2578 *
2579 * This function will record the given rbd_dev's image_id field if
2580 * it can be determined, and in that case will return 0. If any
2581 * errors occur a negative errno will be returned and the rbd_dev's
2582 * image_id field will be unchanged (and should be NULL).
2583 */
2584static int rbd_dev_image_id(struct rbd_device *rbd_dev)
2585{
2586 int ret;
2587 size_t size;
2588 char *object_name;
2589 void *response;
2590 void *p;
2591
2592 /*
2593 * First, see if the format 2 image id file exists, and if
2594 * so, get the image's persistent id from it.
2595 */
2596 size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len;
2597 object_name = kmalloc(size, GFP_NOIO);
2598 if (!object_name)
2599 return -ENOMEM;
2600 sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name);
2601 dout("rbd id object name is %s\n", object_name);
2602
2603 /* Response will be an encoded string, which includes a length */
2604
2605 size = sizeof (__le32) + RBD_IMAGE_ID_LEN_MAX;
2606 response = kzalloc(size, GFP_NOIO);
2607 if (!response) {
2608 ret = -ENOMEM;
2609 goto out;
2610 }
2611
2612 ret = rbd_req_sync_exec(rbd_dev, object_name,
2613 "rbd", "get_id",
2614 NULL, 0,
2615 response, RBD_IMAGE_ID_LEN_MAX,
2616 CEPH_OSD_FLAG_READ, NULL);
2617 dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
2618 if (ret < 0)
2619 goto out;
2620
2621 p = response;
2622 rbd_dev->image_id = ceph_extract_encoded_string(&p,
2623 p + RBD_IMAGE_ID_LEN_MAX,
2624 &rbd_dev->image_id_len,
2625 GFP_NOIO);
2626 if (IS_ERR(rbd_dev->image_id)) {
2627 ret = PTR_ERR(rbd_dev->image_id);
2628 rbd_dev->image_id = NULL;
2629 } else {
2630 dout("image_id is %s\n", rbd_dev->image_id);
2631 }
2632out:
2633 kfree(response);
2634 kfree(object_name);
2635
2636 return ret;
2637}
2638
2556static ssize_t rbd_add(struct bus_type *bus, 2639static ssize_t rbd_add(struct bus_type *bus,
2557 const char *buf, 2640 const char *buf,
2558 size_t count) 2641 size_t count)
@@ -2600,6 +2683,21 @@ static ssize_t rbd_add(struct bus_type *bus,
2600 goto err_out_client; 2683 goto err_out_client;
2601 rbd_dev->pool_id = rc; 2684 rbd_dev->pool_id = rc;
2602 2685
2686 rc = rbd_dev_image_id(rbd_dev);
2687 if (!rc) {
2688 rc = -ENOTSUPP; /* Not actually supporting format 2 yet */
2689 goto err_out_client;
2690 }
2691
2692 /* Version 1 images have no id; empty string is used */
2693
2694 rbd_dev->image_id = kstrdup("", GFP_KERNEL);
2695 if (!rbd_dev->image_id) {
2696 rc = -ENOMEM;
2697 goto err_out_client;
2698 }
2699 rbd_dev->image_id_len = 0;
2700
2603 /* Create the name of the header object */ 2701 /* Create the name of the header object */
2604 2702
2605 rbd_dev->header_name = kmalloc(rbd_dev->image_name_len 2703 rbd_dev->header_name = kmalloc(rbd_dev->image_name_len
@@ -2691,6 +2789,7 @@ err_out_header:
2691err_out_client: 2789err_out_client:
2692 kfree(rbd_dev->header_name); 2790 kfree(rbd_dev->header_name);
2693 rbd_put_client(rbd_dev); 2791 rbd_put_client(rbd_dev);
2792 kfree(rbd_dev->image_id);
2694err_out_args: 2793err_out_args:
2695 kfree(rbd_dev->mapping.snap_name); 2794 kfree(rbd_dev->mapping.snap_name);
2696 kfree(rbd_dev->image_name); 2795 kfree(rbd_dev->image_name);
@@ -2746,6 +2845,7 @@ static void rbd_dev_release(struct device *dev)
2746 2845
2747 /* done with the id, and with the rbd_dev */ 2846 /* done with the id, and with the rbd_dev */
2748 kfree(rbd_dev->mapping.snap_name); 2847 kfree(rbd_dev->mapping.snap_name);
2848 kfree(rbd_dev->image_id);
2749 kfree(rbd_dev->header_name); 2849 kfree(rbd_dev->header_name);
2750 kfree(rbd_dev->pool_name); 2850 kfree(rbd_dev->pool_name);
2751 kfree(rbd_dev->image_name); 2851 kfree(rbd_dev->image_name);