aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-21 13:14:45 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:19:21 -0400
commitcc070d59bc422945f83a89e9d60f749d0f82787d (patch)
tree710d6ad8501cecd11b57bf84c332c98acac95da6 /drivers/block/rbd.c
parent57385b51c3ffd0fed2dd9d5d8e4ec080c85ecbcd (diff)
rbd: get and check striping parameters
If an rbd format 2 image indicates it supports the STRIPINGV2 feature we need to find out its stripe unit and stripe count in order to know whether we can use it. We don't yet support fancy striping fully, but if the default parameters are used the behavior is indistinguishible from non-fancy striping. This is necessary because some images require the STRIPINGV2 feature even if they use the default parameters. (Which is to say the feature bit was erroneously set even if the feature was not used.) This resolves: http://tracker.ceph.com/issues/4709 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 44dcc82770d9..c6a3f46bc8d5 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -317,6 +317,9 @@ struct rbd_device {
317 u64 parent_overlap; 317 u64 parent_overlap;
318 struct rbd_device *parent; 318 struct rbd_device *parent;
319 319
320 u64 stripe_unit;
321 u64 stripe_count;
322
320 /* protects updating the header */ 323 /* protects updating the header */
321 struct rw_semaphore header_rwsem; 324 struct rw_semaphore header_rwsem;
322 325
@@ -3749,6 +3752,56 @@ out_err:
3749 return ret; 3752 return ret;
3750} 3753}
3751 3754
3755static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev)
3756{
3757 struct {
3758 __le64 stripe_unit;
3759 __le64 stripe_count;
3760 } __attribute__ ((packed)) striping_info_buf = { 0 };
3761 size_t size = sizeof (striping_info_buf);
3762 void *p;
3763 u64 obj_size;
3764 u64 stripe_unit;
3765 u64 stripe_count;
3766 int ret;
3767
3768 ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_name,
3769 "rbd", "get_stripe_unit_count", NULL, 0,
3770 (char *)&striping_info_buf, size, NULL);
3771 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret);
3772 if (ret < 0)
3773 return ret;
3774 if (ret < size)
3775 return -ERANGE;
3776
3777 /*
3778 * We don't actually support the "fancy striping" feature
3779 * (STRIPINGV2) yet, but if the striping sizes are the
3780 * defaults the behavior is the same as before. So find
3781 * out, and only fail if the image has non-default values.
3782 */
3783 ret = -EINVAL;
3784 obj_size = (u64)1 << rbd_dev->header.obj_order;
3785 p = &striping_info_buf;
3786 stripe_unit = ceph_decode_64(&p);
3787 if (stripe_unit != obj_size) {
3788 rbd_warn(rbd_dev, "unsupported stripe unit "
3789 "(got %llu want %llu)",
3790 stripe_unit, obj_size);
3791 return -EINVAL;
3792 }
3793 stripe_count = ceph_decode_64(&p);
3794 if (stripe_count != 1) {
3795 rbd_warn(rbd_dev, "unsupported stripe count "
3796 "(got %llu want 1)", stripe_count);
3797 return -EINVAL;
3798 }
3799 rbd_dev->stripe_unit = stripe_unit;
3800 rbd_dev->stripe_count = stripe_count;
3801
3802 return 0;
3803}
3804
3752static char *rbd_dev_image_name(struct rbd_device *rbd_dev) 3805static char *rbd_dev_image_name(struct rbd_device *rbd_dev)
3753{ 3806{
3754 size_t image_id_size; 3807 size_t image_id_size;
@@ -4673,6 +4726,14 @@ static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
4673 goto out_err; 4726 goto out_err;
4674 } 4727 }
4675 4728
4729 /* If the image supports fancy striping, get its parameters */
4730
4731 if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
4732 ret = rbd_dev_v2_striping_info(rbd_dev);
4733 if (ret < 0)
4734 goto out_err;
4735 }
4736
4676 /* crypto and compression type aren't (yet) supported for v2 images */ 4737 /* crypto and compression type aren't (yet) supported for v2 images */
4677 4738
4678 rbd_dev->header.crypt_type = 0; 4739 rbd_dev->header.crypt_type = 0;