diff options
author | Ilya Dryomov <ilya.dryomov@inktank.com> | 2014-05-13 03:19:27 -0400 |
---|---|---|
committer | Yan, Zheng <zheng.z.yan@intel.com> | 2014-06-05 21:29:58 -0400 |
commit | 30ba1f020221991cf239d905c82984958f29bdfe (patch) | |
tree | 343cad430c508927f86c5b756d1dabd50c1aa1d3 /drivers/block/rbd.c | |
parent | 6044cde6f2a94d88142d4401624152a741866338 (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.c | 36 |
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 | */ | ||
4688 | static 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 | |||
4695 | again: | ||
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; |