diff options
author | Alex Elder <elder@inktank.com> | 2013-04-26 16:44:36 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:19:49 -0400 |
commit | 124afba25d58e2b52d7d4bad993065572a28d57f (patch) | |
tree | 3384e0905f24cee6dc06c04df25fa096e5ea49bb /drivers/block/rbd.c | |
parent | b5156e76da01c23e14e962594553f1735b1db298 (diff) |
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>
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r-- | drivers/block/rbd.c | 82 |
1 files changed, 44 insertions, 38 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index b6024a2d7b86..c80fc1a3a604 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -4702,11 +4702,49 @@ out_err: | |||
4702 | return ret; | 4702 | return ret; |
4703 | } | 4703 | } |
4704 | 4704 | ||
4705 | static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) | 4705 | static int rbd_dev_probe_parent(struct rbd_device *rbd_dev) |
4706 | { | 4706 | { |
4707 | struct rbd_device *parent = NULL; | 4707 | struct rbd_device *parent = NULL; |
4708 | struct rbd_spec *parent_spec = NULL; | 4708 | struct rbd_spec *parent_spec; |
4709 | struct rbd_client *rbdc = NULL; | 4709 | struct rbd_client *rbdc; |
4710 | int ret; | ||
4711 | |||
4712 | if (!rbd_dev->parent_spec) | ||
4713 | return 0; | ||
4714 | /* | ||
4715 | * We need to pass a reference to the client and the parent | ||
4716 | * spec when creating the parent rbd_dev. Images related by | ||
4717 | * parent/child relationships always share both. | ||
4718 | */ | ||
4719 | parent_spec = rbd_spec_get(rbd_dev->parent_spec); | ||
4720 | rbdc = __rbd_get_client(rbd_dev->rbd_client); | ||
4721 | |||
4722 | ret = -ENOMEM; | ||
4723 | parent = rbd_dev_create(rbdc, parent_spec); | ||
4724 | if (!parent) | ||
4725 | goto out_err; | ||
4726 | |||
4727 | ret = rbd_dev_image_probe(parent); | ||
4728 | if (ret < 0) | ||
4729 | goto out_err; | ||
4730 | rbd_dev->parent = parent; | ||
4731 | |||
4732 | return 0; | ||
4733 | out_err: | ||
4734 | if (parent) { | ||
4735 | rbd_spec_put(rbd_dev->parent_spec); | ||
4736 | kfree(rbd_dev->header_name); | ||
4737 | rbd_dev_destroy(parent); | ||
4738 | } else { | ||
4739 | rbd_put_client(rbdc); | ||
4740 | rbd_spec_put(parent_spec); | ||
4741 | } | ||
4742 | |||
4743 | return ret; | ||
4744 | } | ||
4745 | |||
4746 | static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) | ||
4747 | { | ||
4710 | int ret; | 4748 | int ret; |
4711 | 4749 | ||
4712 | /* no need to lock here, as rbd_dev is not registered yet */ | 4750 | /* 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) | |||
4747 | if (ret) | 4785 | if (ret) |
4748 | goto err_out_disk; | 4786 | goto err_out_disk; |
4749 | 4787 | ||
4750 | /* | 4788 | ret = rbd_dev_probe_parent(rbd_dev); |
4751 | * At this point cleanup in the event of an error is the job | 4789 | if (ret) |
4752 | * of the sysfs code (initiated by rbd_bus_del_dev()). | 4790 | goto err_out_bus; |
4753 | */ | ||
4754 | /* Probe the parent if there is one */ | ||
4755 | |||
4756 | if (rbd_dev->parent_spec) { | ||
4757 | /* | ||
4758 | * We need to pass a reference to the client and the | ||
4759 | * parent spec when creating the parent rbd_dev. | ||
4760 | * Images related by parent/child relationships | ||
4761 | * always share both. | ||
4762 | */ | ||
4763 | parent_spec = rbd_spec_get(rbd_dev->parent_spec); | ||
4764 | rbdc = __rbd_get_client(rbd_dev->rbd_client); | ||
4765 | |||
4766 | parent = rbd_dev_create(rbdc, parent_spec); | ||
4767 | if (!parent) { | ||
4768 | ret = -ENOMEM; | ||
4769 | goto err_out_spec; | ||
4770 | } | ||
4771 | rbdc = NULL; /* parent now owns reference */ | ||
4772 | parent_spec = NULL; /* parent now owns reference */ | ||
4773 | ret = rbd_dev_image_probe(parent); | ||
4774 | if (ret < 0) | ||
4775 | goto err_out_parent; | ||
4776 | rbd_dev->parent = parent; | ||
4777 | } | ||
4778 | 4791 | ||
4779 | ret = rbd_dev_header_watch_sync(rbd_dev, 1); | 4792 | ret = rbd_dev_header_watch_sync(rbd_dev, 1); |
4780 | if (ret) | 4793 | if (ret) |
@@ -4791,13 +4804,6 @@ static int rbd_dev_probe_finish(struct rbd_device *rbd_dev) | |||
4791 | 4804 | ||
4792 | return ret; | 4805 | return ret; |
4793 | 4806 | ||
4794 | err_out_parent: | ||
4795 | rbd_spec_put(rbd_dev->parent_spec); | ||
4796 | kfree(rbd_dev->header_name); | ||
4797 | rbd_dev_destroy(parent); | ||
4798 | err_out_spec: | ||
4799 | rbd_spec_put(parent_spec); | ||
4800 | rbd_put_client(rbdc); | ||
4801 | err_out_bus: | 4807 | err_out_bus: |
4802 | /* this will also clean up rest of rbd_dev stuff */ | 4808 | /* this will also clean up rest of rbd_dev stuff */ |
4803 | 4809 | ||