summaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-05-13 03:19:27 -0400
committerYan, Zheng <zheng.z.yan@intel.com>2014-06-05 21:29:58 -0400
commit30ba1f020221991cf239d905c82984958f29bdfe (patch)
tree343cad430c508927f86c5b756d1dabd50c1aa1d3 /drivers/block/rbd.c
parent6044cde6f2a94d88142d4401624152a741866338 (diff)
rbd: make sure we have latest osdmap on 'rbd map'
Given an existing idle mapping (img1), mapping an image (img2) in a newly created pool (pool2) fails: $ ceph osd pool create pool1 8 8 $ rbd create --size 1000 pool1/img1 $ sudo rbd map pool1/img1 $ ceph osd pool create pool2 8 8 $ rbd create --size 1000 pool2/img2 $ sudo rbd map pool2/img2 rbd: sysfs write failed rbd: map failed: (2) No such file or directory This is because client instances are shared by default and we don't request an osdmap update when bumping a ref on an existing client. The fix is to use the mon_get_version request to see if the osdmap we have is the latest, and block until the requested update is received if it's not. Fixes: http://tracker.ceph.com/issues/8184 Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 552a2edcaa74..daf7b4659b4a 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -4683,6 +4683,38 @@ out_err:
4683} 4683}
4684 4684
4685/* 4685/*
4686 * Return pool id (>= 0) or a negative error code.
4687 */
4688static int rbd_add_get_pool_id(struct rbd_client *rbdc, const char *pool_name)
4689{
4690 u64 newest_epoch;
4691 unsigned long timeout = rbdc->client->options->mount_timeout * HZ;
4692 int tries = 0;
4693 int ret;
4694
4695again:
4696 ret = ceph_pg_poolid_by_name(rbdc->client->osdc.osdmap, pool_name);
4697 if (ret == -ENOENT && tries++ < 1) {
4698 ret = ceph_monc_do_get_version(&rbdc->client->monc, "osdmap",
4699 &newest_epoch);
4700 if (ret < 0)
4701 return ret;
4702
4703 if (rbdc->client->osdc.osdmap->epoch < newest_epoch) {
4704 ceph_monc_request_next_osdmap(&rbdc->client->monc);
4705 (void) ceph_monc_wait_osdmap(&rbdc->client->monc,
4706 newest_epoch, timeout);
4707 goto again;
4708 } else {
4709 /* the osdmap we have is new enough */
4710 return -ENOENT;
4711 }
4712 }
4713
4714 return ret;
4715}
4716
4717/*
4686 * An rbd format 2 image has a unique identifier, distinct from the 4718 * An rbd format 2 image has a unique identifier, distinct from the
4687 * name given to it by the user. Internally, that identifier is 4719 * name given to it by the user. Internally, that identifier is
4688 * what's used to specify the names of objects related to the image. 4720 * what's used to specify the names of objects related to the image.
@@ -5053,7 +5085,6 @@ static ssize_t do_rbd_add(struct bus_type *bus,
5053 struct rbd_options *rbd_opts = NULL; 5085 struct rbd_options *rbd_opts = NULL;
5054 struct rbd_spec *spec = NULL; 5086 struct rbd_spec *spec = NULL;
5055 struct rbd_client *rbdc; 5087 struct rbd_client *rbdc;
5056 struct ceph_osd_client *osdc;
5057 bool read_only; 5088 bool read_only;
5058 int rc = -ENOMEM; 5089 int rc = -ENOMEM;
5059 5090
@@ -5075,8 +5106,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
5075 } 5106 }
5076 5107
5077 /* pick the pool */ 5108 /* pick the pool */
5078 osdc = &rbdc->client->osdc; 5109 rc = rbd_add_get_pool_id(rbdc, spec->pool_name);
5079 rc = ceph_pg_poolid_by_name(osdc->osdmap, spec->pool_name);
5080 if (rc < 0) 5110 if (rc < 0)
5081 goto err_out_client; 5111 goto err_out_client;
5082 spec->pool_id = (u64)rc; 5112 spec->pool_id = (u64)rc;