Commit b644de2b authored by Alex Elder's avatar Alex Elder Committed by Sage Weil

rbd: set up watch in rbd_dev_image_probe()

Move setting up the watch request for an image so it's done in
rbd_dev_image_probe() rather than rbd_dev_probe_finish().  Move
it all the way up to before doing the initial probe.  This avoids
a potential race condition, in which we get (and use) the initial
snapshot context for an image, and it gets changed between that
time and the time we get the watch set up.

This resolves:
    http://tracker.ceph.com/issues/3871Signed-off-by: default avatarAlex Elder <elder@inktank.com>
Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
parent 96f03e08
......@@ -4721,11 +4721,6 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
{
int ret;
int tmp;
ret = rbd_dev_header_watch_sync(rbd_dev, 1);
if (ret)
return ret;
ret = rbd_dev_mapping_set(rbd_dev);
if (ret)
......@@ -4773,9 +4768,6 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
unregister_blkdev(rbd_dev->major, rbd_dev->name);
err_out_id:
rbd_dev_id_put(rbd_dev);
tmp = rbd_dev_header_watch_sync(rbd_dev, 0);
if (tmp)
rbd_warn(rbd_dev, "failed to cancel watch event (%d)\n", ret);
rbd_dev_mapping_clear(rbd_dev);
return ret;
......@@ -4816,6 +4808,7 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev)
static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
{
int ret;
int tmp;
/*
* Get the id from the image id object. If it's not a
......@@ -4832,16 +4825,20 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
if (ret)
goto err_out_format;
ret = rbd_dev_header_watch_sync(rbd_dev, 1);
if (ret)
goto out_header_name;
if (rbd_dev->image_format == 1)
ret = rbd_dev_v1_probe(rbd_dev);
else
ret = rbd_dev_v2_probe(rbd_dev);
if (ret)
goto out_header_name;
goto err_out_watch;
ret = rbd_dev_snaps_update(rbd_dev);
if (ret)
goto out_header_name;
goto err_out_watch;
ret = rbd_dev_spec_update(rbd_dev);
if (ret)
......@@ -4861,6 +4858,10 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev)
rbd_header_free(&rbd_dev->header);
err_out_snaps:
rbd_remove_all_snaps(rbd_dev);
err_out_watch:
tmp = rbd_dev_header_watch_sync(rbd_dev, 0);
if (tmp)
rbd_warn(rbd_dev, "unable to tear down watch request\n");
out_header_name:
kfree(rbd_dev->header_name);
rbd_dev->header_name = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment