From: Alex Elder Date: Sat, 27 Apr 2013 14:59:30 +0000 (-0500) Subject: rbd: move more initialization into rbd_dev_image_probe() X-Git-Tag: v3.10-rc1~81^2~33 X-Git-Url: http://pileus.org/git/?p=~andy%2Flinux;a=commitdiff_plain;h=9bb81c9be90c1ad265547f0a40f543548d263fb4 rbd: move more initialization into rbd_dev_image_probe() Move a block of initialization related to the "ceph-side" of an rbd image out of rbd_dev_probe_finish() and into rbd_dev_image_probe(). Add appropriate error handling to clean things up in the event any of these new functions return an error. We know that rbd_dev_snaps_update(), rbd_dev_spec_update(), and rbd_dev_probe_parent() all clean up after themselves before they return an error, so no special cleanup is required except when an earlier call succeeds. Since rbd_dev_spec_update() only updates the spec field (whose cleanup will be handled by dropping the last reference to the spec) there is no cleanup action associatied with that. Signed-off-by: Alex Elder Reviewed-by: Josh Durgin --- diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index e86238c9067..ebf4d470e13 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4755,26 +4755,13 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) { int ret; - /* no need to lock here, as rbd_dev is not registered yet */ - ret = rbd_dev_snaps_update(rbd_dev); - if (ret) - return ret; - - ret = rbd_dev_spec_update(rbd_dev); - if (ret) - goto err_out_snaps; - ret = rbd_dev_header_watch_sync(rbd_dev, 1); if (ret) - goto err_out_snaps; + return ret; ret = rbd_dev_mapping_set(rbd_dev); if (ret) - goto err_out_snaps; - - ret = rbd_dev_probe_parent(rbd_dev); - if (ret) - goto err_out_mapping; + return ret; /* generate unique id: find highest unique id, add one */ rbd_dev_id_get(rbd_dev); @@ -4818,11 +4805,7 @@ err_out_blkdev: unregister_blkdev(rbd_dev->major, rbd_dev->name); err_out_id: rbd_dev_id_put(rbd_dev); - rbd_dev_remove_parent(rbd_dev); -err_out_mapping: rbd_dev_mapping_clear(rbd_dev); -err_out_snaps: - rbd_remove_all_snaps(rbd_dev); return ret; } @@ -4854,11 +4837,28 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev) if (ret) goto out_err; + ret = rbd_dev_snaps_update(rbd_dev); + if (ret) + goto out_err; + + ret = rbd_dev_spec_update(rbd_dev); + if (ret) + goto err_out_snaps; + + ret = rbd_dev_probe_parent(rbd_dev); + if (ret) + goto err_out_snaps; + ret = rbd_dev_probe_finish(rbd_dev); if (ret) - rbd_header_free(&rbd_dev->header); + goto err_out_parent; return ret; +err_out_parent: + rbd_dev_remove_parent(rbd_dev); + rbd_header_free(&rbd_dev->header); +err_out_snaps: + rbd_remove_all_snaps(rbd_dev); out_err: kfree(rbd_dev->spec->image_id); rbd_dev->spec->image_id = NULL;