diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/rbd.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index d3d15d06abc0..fd9656b5fdb9 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1707,6 +1707,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) | |||
1707 | &rbd_dev->watch_event); | 1707 | &rbd_dev->watch_event); |
1708 | if (ret < 0) | 1708 | if (ret < 0) |
1709 | return ret; | 1709 | return ret; |
1710 | rbd_assert(rbd_dev->watch_event != NULL); | ||
1710 | } | 1711 | } |
1711 | 1712 | ||
1712 | ret = -ENOMEM; | 1713 | ret = -ENOMEM; |
@@ -1726,32 +1727,43 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) | |||
1726 | if (!obj_request->osd_req) | 1727 | if (!obj_request->osd_req) |
1727 | goto out_cancel; | 1728 | goto out_cancel; |
1728 | 1729 | ||
1729 | if (start) { | 1730 | if (start) |
1730 | ceph_osdc_set_request_linger(osdc, obj_request->osd_req); | 1731 | ceph_osdc_set_request_linger(osdc, obj_request->osd_req); |
1731 | rbd_dev->watch_request = obj_request; | 1732 | else |
1732 | } else { | ||
1733 | ceph_osdc_unregister_linger_request(osdc, | 1733 | ceph_osdc_unregister_linger_request(osdc, |
1734 | rbd_dev->watch_request->osd_req); | 1734 | rbd_dev->watch_request->osd_req); |
1735 | rbd_dev->watch_request = NULL; | ||
1736 | } | ||
1737 | ret = rbd_obj_request_submit(osdc, obj_request); | 1735 | ret = rbd_obj_request_submit(osdc, obj_request); |
1738 | if (ret) | 1736 | if (ret) |
1739 | goto out_cancel; | 1737 | goto out_cancel; |
1740 | ret = rbd_obj_request_wait(obj_request); | 1738 | ret = rbd_obj_request_wait(obj_request); |
1741 | if (ret) | 1739 | if (ret) |
1742 | goto out_cancel; | 1740 | goto out_cancel; |
1743 | |||
1744 | ret = obj_request->result; | 1741 | ret = obj_request->result; |
1745 | if (ret) | 1742 | if (ret) |
1746 | goto out_cancel; | 1743 | goto out_cancel; |
1747 | 1744 | ||
1748 | if (start) | 1745 | /* |
1749 | goto done; /* Done if setting up the watch request */ | 1746 | * A watch request is set to linger, so the underlying osd |
1747 | * request won't go away until we unregister it. We retain | ||
1748 | * a pointer to the object request during that time (in | ||
1749 | * rbd_dev->watch_request), so we'll keep a reference to | ||
1750 | * it. We'll drop that reference (below) after we've | ||
1751 | * unregistered it. | ||
1752 | */ | ||
1753 | if (start) { | ||
1754 | rbd_dev->watch_request = obj_request; | ||
1755 | |||
1756 | return 0; | ||
1757 | } | ||
1758 | |||
1759 | /* We have successfully torn down the watch request */ | ||
1760 | |||
1761 | rbd_obj_request_put(rbd_dev->watch_request); | ||
1762 | rbd_dev->watch_request = NULL; | ||
1750 | out_cancel: | 1763 | out_cancel: |
1751 | /* Cancel the event if we're tearing down, or on error */ | 1764 | /* Cancel the event if we're tearing down, or on error */ |
1752 | ceph_osdc_cancel_event(rbd_dev->watch_event); | 1765 | ceph_osdc_cancel_event(rbd_dev->watch_event); |
1753 | rbd_dev->watch_event = NULL; | 1766 | rbd_dev->watch_event = NULL; |
1754 | done: | ||
1755 | if (obj_request) | 1767 | if (obj_request) |
1756 | rbd_obj_request_put(obj_request); | 1768 | rbd_obj_request_put(obj_request); |
1757 | 1769 | ||