2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-30 16:13:54 +08:00

rbd: encapsulate probing for parent devices

Encapsulate the code that probes for an rbd device's parent images
into a new function, rbd_dev_probe_parent().

Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
Alex Elder 2013-04-26 15:44:36 -05:00 committed by Sage Weil
parent b5156e76da
commit 124afba25d

View File

@ -4702,11 +4702,49 @@ out_err:
return ret;
}
static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
{
struct rbd_device *parent = NULL;
struct rbd_spec *parent_spec = NULL;
struct rbd_client *rbdc = NULL;
struct rbd_spec *parent_spec;
struct rbd_client *rbdc;
int ret;
if (!rbd_dev->parent_spec)
return 0;
/*
* We need to pass a reference to the client and the parent
* spec when creating the parent rbd_dev. Images related by
* parent/child relationships always share both.
*/
parent_spec = rbd_spec_get(rbd_dev->parent_spec);
rbdc = __rbd_get_client(rbd_dev->rbd_client);
ret = -ENOMEM;
parent = rbd_dev_create(rbdc, parent_spec);
if (!parent)
goto out_err;
ret = rbd_dev_image_probe(parent);
if (ret < 0)
goto out_err;
rbd_dev->parent = parent;
return 0;
out_err:
if (parent) {
rbd_spec_put(rbd_dev->parent_spec);
kfree(rbd_dev->header_name);
rbd_dev_destroy(parent);
} else {
rbd_put_client(rbdc);
rbd_spec_put(parent_spec);
}
return ret;
}
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 */
@ -4747,34 +4785,9 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
if (ret)
goto err_out_disk;
/*
* At this point cleanup in the event of an error is the job
* of the sysfs code (initiated by rbd_bus_del_dev()).
*/
/* Probe the parent if there is one */
if (rbd_dev->parent_spec) {
/*
* We need to pass a reference to the client and the
* parent spec when creating the parent rbd_dev.
* Images related by parent/child relationships
* always share both.
*/
parent_spec = rbd_spec_get(rbd_dev->parent_spec);
rbdc = __rbd_get_client(rbd_dev->rbd_client);
parent = rbd_dev_create(rbdc, parent_spec);
if (!parent) {
ret = -ENOMEM;
goto err_out_spec;
}
rbdc = NULL; /* parent now owns reference */
parent_spec = NULL; /* parent now owns reference */
ret = rbd_dev_image_probe(parent);
if (ret < 0)
goto err_out_parent;
rbd_dev->parent = parent;
}
ret = rbd_dev_probe_parent(rbd_dev);
if (ret)
goto err_out_bus;
ret = rbd_dev_header_watch_sync(rbd_dev, 1);
if (ret)
@ -4791,13 +4804,6 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev)
return ret;
err_out_parent:
rbd_spec_put(rbd_dev->parent_spec);
kfree(rbd_dev->header_name);
rbd_dev_destroy(parent);
err_out_spec:
rbd_spec_put(parent_spec);
rbd_put_client(rbdc);
err_out_bus:
/* this will also clean up rest of rbd_dev stuff */