aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-19 16:34:50 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:19:11 -0400
commitf1a4739f333b519fe041e1ad81d9b31c94b9d6a3 (patch)
treec86ebedf87940ce47adfb79e1370c85d41da1d8d
parentb9434c5b43d1a90e762fe64169862fb198746935 (diff)
rbd: support page array image requests
This patch adds the ability to build an image request whose data will be written from or read into memory described by a page array. (Previously only bio lists were supported.) Originally this was going to define a new function for this purpose but it was largely identical to the rbd_img_request_fill_bio(). So instead, rbd_img_request_fill_bio() has been generalized to handle both types of image request. For the moment we still only fill image requests with bio data. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r--drivers/block/rbd.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 06bbd55c0ea1..8a7216d784d7 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1780,6 +1780,13 @@ static bool rbd_img_obj_end_request(struct rbd_obj_request *obj_request)
1780 img_request->result = result; 1780 img_request->result = result;
1781 } 1781 }
1782 1782
1783 /* Image object requests don't own their page array */
1784
1785 if (obj_request->type == OBJ_REQUEST_PAGES) {
1786 obj_request->pages = NULL;
1787 obj_request->page_count = 0;
1788 }
1789
1783 if (img_request_child_test(img_request)) { 1790 if (img_request_child_test(img_request)) {
1784 rbd_assert(img_request->obj_request != NULL); 1791 rbd_assert(img_request->obj_request != NULL);
1785 more = obj_request->which < img_request->obj_request_count - 1; 1792 more = obj_request->which < img_request->obj_request_count - 1;
@@ -1830,30 +1837,48 @@ out:
1830 rbd_img_request_complete(img_request); 1837 rbd_img_request_complete(img_request);
1831} 1838}
1832 1839
1833static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, 1840/*
1834 struct bio *bio_list) 1841 * Split up an image request into one or more object requests, each
1842 * to a different object. The "type" parameter indicates whether
1843 * "data_desc" is the pointer to the head of a list of bio
1844 * structures, or the base of a page array. In either case this
1845 * function assumes data_desc describes memory sufficient to hold
1846 * all data described by the image request.
1847 */
1848static int rbd_img_request_fill(struct rbd_img_request *img_request,
1849 enum obj_request_type type,
1850 void *data_desc)
1835{ 1851{
1836 struct rbd_device *rbd_dev = img_request->rbd_dev; 1852 struct rbd_device *rbd_dev = img_request->rbd_dev;
1837 struct rbd_obj_request *obj_request = NULL; 1853 struct rbd_obj_request *obj_request = NULL;
1838 struct rbd_obj_request *next_obj_request; 1854 struct rbd_obj_request *next_obj_request;
1839 bool write_request = img_request_write_test(img_request); 1855 bool write_request = img_request_write_test(img_request);
1840 unsigned int bio_offset; 1856 struct bio *bio_list;
1857 unsigned int bio_offset = 0;
1858 struct page **pages;
1841 u64 img_offset; 1859 u64 img_offset;
1842 u64 resid; 1860 u64 resid;
1843 u16 opcode; 1861 u16 opcode;
1844 1862
1845 dout("%s: img %p bio %p\n", __func__, img_request, bio_list); 1863 dout("%s: img %p type %d data_desc %p\n", __func__, img_request,
1864 (int)type, data_desc);
1846 1865
1847 opcode = write_request ? CEPH_OSD_OP_WRITE : CEPH_OSD_OP_READ; 1866 opcode = write_request ? CEPH_OSD_OP_WRITE : CEPH_OSD_OP_READ;
1848 bio_offset = 0;
1849 img_offset = img_request->offset; 1867 img_offset = img_request->offset;
1850 rbd_assert(img_offset == bio_list->bi_sector << SECTOR_SHIFT);
1851 resid = img_request->length; 1868 resid = img_request->length;
1852 rbd_assert(resid > 0); 1869 rbd_assert(resid > 0);
1870
1871 if (type == OBJ_REQUEST_BIO) {
1872 bio_list = data_desc;
1873 rbd_assert(img_offset == bio_list->bi_sector << SECTOR_SHIFT);
1874 } else {
1875 rbd_assert(type == OBJ_REQUEST_PAGES);
1876 pages = data_desc;
1877 }
1878
1853 while (resid) { 1879 while (resid) {
1854 struct ceph_osd_request *osd_req; 1880 struct ceph_osd_request *osd_req;
1855 const char *object_name; 1881 const char *object_name;
1856 unsigned int clone_size;
1857 u64 offset; 1882 u64 offset;
1858 u64 length; 1883 u64 length;
1859 1884
@@ -1863,19 +1888,33 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1863 offset = rbd_segment_offset(rbd_dev, img_offset); 1888 offset = rbd_segment_offset(rbd_dev, img_offset);
1864 length = rbd_segment_length(rbd_dev, img_offset, resid); 1889 length = rbd_segment_length(rbd_dev, img_offset, resid);
1865 obj_request = rbd_obj_request_create(object_name, 1890 obj_request = rbd_obj_request_create(object_name,
1866 offset, length, 1891 offset, length, type);
1867 OBJ_REQUEST_BIO);
1868 kfree(object_name); /* object request has its own copy */ 1892 kfree(object_name); /* object request has its own copy */
1869 if (!obj_request) 1893 if (!obj_request)
1870 goto out_unwind; 1894 goto out_unwind;
1871 1895
1872 rbd_assert(length <= (u64) UINT_MAX); 1896 if (type == OBJ_REQUEST_BIO) {
1873 clone_size = (unsigned int) length; 1897 unsigned int clone_size;
1874 obj_request->bio_list = bio_chain_clone_range(&bio_list, 1898
1875 &bio_offset, clone_size, 1899 rbd_assert(length <= (u64)UINT_MAX);
1876 GFP_ATOMIC); 1900 clone_size = (unsigned int)length;
1877 if (!obj_request->bio_list) 1901 obj_request->bio_list =
1878 goto out_partial; 1902 bio_chain_clone_range(&bio_list,
1903 &bio_offset,
1904 clone_size,
1905 GFP_ATOMIC);
1906 if (!obj_request->bio_list)
1907 goto out_partial;
1908 } else {
1909 unsigned int page_count;
1910
1911 obj_request->pages = pages;
1912 page_count = (u32)calc_pages_for(offset, length);
1913 obj_request->page_count = page_count;
1914 if ((offset + length) & ~PAGE_MASK)
1915 page_count--; /* more on last page */
1916 pages += page_count;
1917 }
1879 1918
1880 osd_req = rbd_osd_req_create(rbd_dev, write_request, 1919 osd_req = rbd_osd_req_create(rbd_dev, write_request,
1881 obj_request); 1920 obj_request);
@@ -1886,8 +1925,13 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1886 1925
1887 osd_req_op_extent_init(osd_req, 0, opcode, offset, length, 1926 osd_req_op_extent_init(osd_req, 0, opcode, offset, length,
1888 0, 0); 1927 0, 0);
1889 osd_req_op_extent_osd_data_bio(osd_req, 0, 1928 if (type == OBJ_REQUEST_BIO)
1890 obj_request->bio_list, obj_request->length); 1929 osd_req_op_extent_osd_data_bio(osd_req, 0,
1930 obj_request->bio_list, length);
1931 else
1932 osd_req_op_extent_osd_data_pages(osd_req, 0,
1933 obj_request->pages, length,
1934 offset & ~PAGE_MASK, false, false);
1891 1935
1892 if (write_request) 1936 if (write_request)
1893 rbd_osd_req_format_write(obj_request); 1937 rbd_osd_req_format_write(obj_request);
@@ -2120,7 +2164,8 @@ static void rbd_img_parent_read(struct rbd_obj_request *obj_request)
2120 rbd_obj_request_get(obj_request); 2164 rbd_obj_request_get(obj_request);
2121 img_request->obj_request = obj_request; 2165 img_request->obj_request = obj_request;
2122 2166
2123 result = rbd_img_request_fill_bio(img_request, obj_request->bio_list); 2167 result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
2168 obj_request->bio_list);
2124 if (result) 2169 if (result)
2125 goto out_err; 2170 goto out_err;
2126 2171
@@ -2425,7 +2470,8 @@ static void rbd_request_fn(struct request_queue *q)
2425 2470
2426 img_request->rq = rq; 2471 img_request->rq = rq;
2427 2472
2428 result = rbd_img_request_fill_bio(img_request, rq->bio); 2473 result = rbd_img_request_fill(img_request, OBJ_REQUEST_BIO,
2474 rq->bio);
2429 if (!result) 2475 if (!result)
2430 result = rbd_img_request_submit(img_request); 2476 result = rbd_img_request_submit(img_request);
2431 if (result) 2477 if (result)