aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c128
1 files changed, 62 insertions, 66 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4cfe9f96589e..db29783436c8 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1519,6 +1519,57 @@ static void rbd_img_request_destroy(struct kref *kref)
1519 kfree(img_request); 1519 kfree(img_request);
1520} 1520}
1521 1521
1522static void rbd_img_obj_callback(struct rbd_obj_request *obj_request)
1523{
1524 struct rbd_img_request *img_request;
1525 u32 which = obj_request->which;
1526 bool more = true;
1527
1528 img_request = obj_request->img_request;
1529
1530 dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
1531 rbd_assert(img_request != NULL);
1532 rbd_assert(img_request->rq != NULL);
1533 rbd_assert(img_request->obj_request_count > 0);
1534 rbd_assert(which != BAD_WHICH);
1535 rbd_assert(which < img_request->obj_request_count);
1536 rbd_assert(which >= img_request->next_completion);
1537
1538 spin_lock_irq(&img_request->completion_lock);
1539 if (which != img_request->next_completion)
1540 goto out;
1541
1542 for_each_obj_request_from(img_request, obj_request) {
1543 unsigned int xferred;
1544 int result;
1545
1546 rbd_assert(more);
1547 rbd_assert(which < img_request->obj_request_count);
1548
1549 if (!obj_request_done_test(obj_request))
1550 break;
1551
1552 rbd_assert(obj_request->xferred <= (u64) UINT_MAX);
1553 xferred = (unsigned int) obj_request->xferred;
1554 result = (int) obj_request->result;
1555 if (result)
1556 rbd_warn(NULL, "obj_request %s result %d xferred %u\n",
1557 img_request->write_request ? "write" : "read",
1558 result, xferred);
1559
1560 more = blk_end_request(img_request->rq, result, xferred);
1561 which++;
1562 }
1563
1564 rbd_assert(more ^ (which == img_request->obj_request_count));
1565 img_request->next_completion = which;
1566out:
1567 spin_unlock_irq(&img_request->completion_lock);
1568
1569 if (!more)
1570 rbd_img_request_complete(img_request);
1571}
1572
1522static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, 1573static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1523 struct bio *bio_list) 1574 struct bio *bio_list)
1524{ 1575{
@@ -1572,6 +1623,7 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1572 if (!osd_req) 1623 if (!osd_req)
1573 goto out_partial; 1624 goto out_partial;
1574 obj_request->osd_req = osd_req; 1625 obj_request->osd_req = osd_req;
1626 obj_request->callback = rbd_img_obj_callback;
1575 1627
1576 osd_data = write_request ? &osd_req->r_data_out 1628 osd_data = write_request ? &osd_req->r_data_out
1577 : &osd_req->r_data_in; 1629 : &osd_req->r_data_in;
@@ -1582,8 +1634,6 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1582 osd_req_op_extent_osd_data(osd_req, 0, osd_data); 1634 osd_req_op_extent_osd_data(osd_req, 0, osd_data);
1583 rbd_osd_req_format(obj_request, write_request); 1635 rbd_osd_req_format(obj_request, write_request);
1584 1636
1585 /* status and version are initially zero-filled */
1586
1587 rbd_img_obj_request_add(img_request, obj_request); 1637 rbd_img_obj_request_add(img_request, obj_request);
1588 1638
1589 image_offset += length; 1639 image_offset += length;
@@ -1601,57 +1651,6 @@ out_unwind:
1601 return -ENOMEM; 1651 return -ENOMEM;
1602} 1652}
1603 1653
1604static void rbd_img_obj_callback(struct rbd_obj_request *obj_request)
1605{
1606 struct rbd_img_request *img_request;
1607 u32 which = obj_request->which;
1608 bool more = true;
1609
1610 img_request = obj_request->img_request;
1611
1612 dout("%s: img %p obj %p\n", __func__, img_request, obj_request);
1613 rbd_assert(img_request != NULL);
1614 rbd_assert(img_request->rq != NULL);
1615 rbd_assert(img_request->obj_request_count > 0);
1616 rbd_assert(which != BAD_WHICH);
1617 rbd_assert(which < img_request->obj_request_count);
1618 rbd_assert(which >= img_request->next_completion);
1619
1620 spin_lock_irq(&img_request->completion_lock);
1621 if (which != img_request->next_completion)
1622 goto out;
1623
1624 for_each_obj_request_from(img_request, obj_request) {
1625 unsigned int xferred;
1626 int result;
1627
1628 rbd_assert(more);
1629 rbd_assert(which < img_request->obj_request_count);
1630
1631 if (!obj_request_done_test(obj_request))
1632 break;
1633
1634 rbd_assert(obj_request->xferred <= (u64) UINT_MAX);
1635 xferred = (unsigned int) obj_request->xferred;
1636 result = (int) obj_request->result;
1637 if (result)
1638 rbd_warn(NULL, "obj_request %s result %d xferred %u\n",
1639 img_request->write_request ? "write" : "read",
1640 result, xferred);
1641
1642 more = blk_end_request(img_request->rq, result, xferred);
1643 which++;
1644 }
1645
1646 rbd_assert(more ^ (which == img_request->obj_request_count));
1647 img_request->next_completion = which;
1648out:
1649 spin_unlock_irq(&img_request->completion_lock);
1650
1651 if (!more)
1652 rbd_img_request_complete(img_request);
1653}
1654
1655static int rbd_img_request_submit(struct rbd_img_request *img_request) 1654static int rbd_img_request_submit(struct rbd_img_request *img_request)
1656{ 1655{
1657 struct rbd_device *rbd_dev = img_request->rbd_dev; 1656 struct rbd_device *rbd_dev = img_request->rbd_dev;
@@ -1663,7 +1662,6 @@ static int rbd_img_request_submit(struct rbd_img_request *img_request)
1663 for_each_obj_request_safe(img_request, obj_request, next_obj_request) { 1662 for_each_obj_request_safe(img_request, obj_request, next_obj_request) {
1664 int ret; 1663 int ret;
1665 1664
1666 obj_request->callback = rbd_img_obj_callback;
1667 ret = rbd_obj_request_submit(osdc, obj_request); 1665 ret = rbd_obj_request_submit(osdc, obj_request);
1668 if (ret) 1666 if (ret)
1669 return ret; 1667 return ret;
@@ -1682,7 +1680,7 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev,
1682 u64 ver, u64 notify_id) 1680 u64 ver, u64 notify_id)
1683{ 1681{
1684 struct rbd_obj_request *obj_request; 1682 struct rbd_obj_request *obj_request;
1685 struct ceph_osd_client *osdc; 1683 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
1686 int ret; 1684 int ret;
1687 1685
1688 obj_request = rbd_obj_request_create(rbd_dev->header_name, 0, 0, 1686 obj_request = rbd_obj_request_create(rbd_dev->header_name, 0, 0,
@@ -1694,13 +1692,12 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev,
1694 obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, obj_request); 1692 obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, obj_request);
1695 if (!obj_request->osd_req) 1693 if (!obj_request->osd_req)
1696 goto out; 1694 goto out;
1695 obj_request->callback = rbd_obj_request_put;
1697 1696
1698 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_NOTIFY_ACK, 1697 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_NOTIFY_ACK,
1699 notify_id, ver, 0); 1698 notify_id, ver, 0);
1700 rbd_osd_req_format(obj_request, false); 1699 rbd_osd_req_format(obj_request, false);
1701 1700
1702 osdc = &rbd_dev->rbd_client->client->osdc;
1703 obj_request->callback = rbd_obj_request_put;
1704 ret = rbd_obj_request_submit(osdc, obj_request); 1701 ret = rbd_obj_request_submit(osdc, obj_request);
1705out: 1702out:
1706 if (ret) 1703 if (ret)
@@ -1760,16 +1757,17 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
1760 if (!obj_request->osd_req) 1757 if (!obj_request->osd_req)
1761 goto out_cancel; 1758 goto out_cancel;
1762 1759
1763 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH,
1764 rbd_dev->watch_event->cookie,
1765 rbd_dev->header.obj_version, start);
1766 rbd_osd_req_format(obj_request, true);
1767
1768 if (start) 1760 if (start)
1769 ceph_osdc_set_request_linger(osdc, obj_request->osd_req); 1761 ceph_osdc_set_request_linger(osdc, obj_request->osd_req);
1770 else 1762 else
1771 ceph_osdc_unregister_linger_request(osdc, 1763 ceph_osdc_unregister_linger_request(osdc,
1772 rbd_dev->watch_request->osd_req); 1764 rbd_dev->watch_request->osd_req);
1765
1766 osd_req_op_watch_init(obj_request->osd_req, 0, CEPH_OSD_OP_WATCH,
1767 rbd_dev->watch_event->cookie,
1768 rbd_dev->header.obj_version, start);
1769 rbd_osd_req_format(obj_request, true);
1770
1773 ret = rbd_obj_request_submit(osdc, obj_request); 1771 ret = rbd_obj_request_submit(osdc, obj_request);
1774 if (ret) 1772 if (ret)
1775 goto out_cancel; 1773 goto out_cancel;
@@ -1821,9 +1819,9 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
1821 size_t inbound_size, 1819 size_t inbound_size,
1822 u64 *version) 1820 u64 *version)
1823{ 1821{
1822 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
1824 struct rbd_obj_request *obj_request; 1823 struct rbd_obj_request *obj_request;
1825 struct ceph_osd_data *osd_data; 1824 struct ceph_osd_data *osd_data;
1826 struct ceph_osd_client *osdc;
1827 struct page **pages; 1825 struct page **pages;
1828 u32 page_count; 1826 u32 page_count;
1829 int ret; 1827 int ret;
@@ -1862,7 +1860,6 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
1862 osd_req_op_cls_response_data(obj_request->osd_req, 0, osd_data); 1860 osd_req_op_cls_response_data(obj_request->osd_req, 0, osd_data);
1863 rbd_osd_req_format(obj_request, false); 1861 rbd_osd_req_format(obj_request, false);
1864 1862
1865 osdc = &rbd_dev->rbd_client->client->osdc;
1866 ret = rbd_obj_request_submit(osdc, obj_request); 1863 ret = rbd_obj_request_submit(osdc, obj_request);
1867 if (ret) 1864 if (ret)
1868 goto out; 1865 goto out;
@@ -2038,9 +2035,9 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
2038 char *buf, u64 *version) 2035 char *buf, u64 *version)
2039 2036
2040{ 2037{
2038 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
2041 struct rbd_obj_request *obj_request; 2039 struct rbd_obj_request *obj_request;
2042 struct ceph_osd_data *osd_data; 2040 struct ceph_osd_data *osd_data;
2043 struct ceph_osd_client *osdc;
2044 struct page **pages = NULL; 2041 struct page **pages = NULL;
2045 u32 page_count; 2042 u32 page_count;
2046 size_t size; 2043 size_t size;
@@ -2074,7 +2071,6 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
2074 osd_req_op_extent_osd_data(obj_request->osd_req, 0, osd_data); 2071 osd_req_op_extent_osd_data(obj_request->osd_req, 0, osd_data);
2075 rbd_osd_req_format(obj_request, false); 2072 rbd_osd_req_format(obj_request, false);
2076 2073
2077 osdc = &rbd_dev->rbd_client->client->osdc;
2078 ret = rbd_obj_request_submit(osdc, obj_request); 2074 ret = rbd_obj_request_submit(osdc, obj_request);
2079 if (ret) 2075 if (ret)
2080 goto out; 2076 goto out;