diff options
author | Alex Elder <elder@inktank.com> | 2013-03-08 21:58:59 -0500 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:16:51 -0400 |
commit | afb3d90e205140415477d501ff9e2a33ff0b197f (patch) | |
tree | 2c32016324a858846cf4f1b7d6760195096f96e5 /net/ceph/messenger.c | |
parent | 34d2d2006cc82fd21f716e10568b8c8b4ef61c0e (diff) |
libceph: define and use ceph_tcp_recvpage()
Define a new function ceph_tcp_recvpage() that behaves in a way
comparable to ceph_tcp_sendpage().
Rearrange the code in both read_partial_message_pages() and
read_partial_message_bio() so they have matching structure,
(similar to what's in write_partial_msg_pages()), and use
this new function.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r-- | net/ceph/messenger.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 6e0bd36d676a..3120a6c81a76 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -471,6 +471,22 @@ static int ceph_tcp_recvmsg(struct socket *sock, void *buf, size_t len) | |||
471 | return r; | 471 | return r; |
472 | } | 472 | } |
473 | 473 | ||
474 | static int ceph_tcp_recvpage(struct socket *sock, struct page *page, | ||
475 | int page_offset, size_t length) | ||
476 | { | ||
477 | void *kaddr; | ||
478 | int ret; | ||
479 | |||
480 | BUG_ON(page_offset + length > PAGE_SIZE); | ||
481 | |||
482 | kaddr = kmap(page); | ||
483 | BUG_ON(!kaddr); | ||
484 | ret = ceph_tcp_recvmsg(sock, kaddr + page_offset, length); | ||
485 | kunmap(page); | ||
486 | |||
487 | return ret; | ||
488 | } | ||
489 | |||
474 | /* | 490 | /* |
475 | * write something. @more is true if caller will be sending more data | 491 | * write something. @more is true if caller will be sending more data |
476 | * shortly. | 492 | * shortly. |
@@ -1809,26 +1825,36 @@ static int read_partial_message_pages(struct ceph_connection *con, | |||
1809 | { | 1825 | { |
1810 | struct ceph_msg_pos *msg_pos = &con->in_msg_pos; | 1826 | struct ceph_msg_pos *msg_pos = &con->in_msg_pos; |
1811 | struct page *page; | 1827 | struct page *page; |
1812 | void *p; | 1828 | size_t page_offset; |
1829 | size_t length; | ||
1830 | unsigned int left; | ||
1813 | int ret; | 1831 | int ret; |
1814 | int left; | ||
1815 | 1832 | ||
1816 | left = min((int)(data_len - msg_pos->data_pos), | ||
1817 | (int)(PAGE_SIZE - msg_pos->page_pos)); | ||
1818 | /* (page) data */ | 1833 | /* (page) data */ |
1819 | BUG_ON(pages == NULL); | 1834 | BUG_ON(pages == NULL); |
1820 | page = pages[msg_pos->page]; | 1835 | page = pages[msg_pos->page]; |
1821 | p = kmap(page); | 1836 | page_offset = msg_pos->page_pos; |
1822 | ret = ceph_tcp_recvmsg(con->sock, p + msg_pos->page_pos, left); | 1837 | BUG_ON(msg_pos->data_pos >= data_len); |
1823 | if (ret > 0 && do_datacrc) | 1838 | left = data_len - msg_pos->data_pos; |
1824 | con->in_data_crc = | 1839 | BUG_ON(page_offset >= PAGE_SIZE); |
1825 | crc32c(con->in_data_crc, | 1840 | length = min_t(unsigned int, PAGE_SIZE - page_offset, left); |
1826 | p + msg_pos->page_pos, ret); | 1841 | |
1827 | kunmap(page); | 1842 | ret = ceph_tcp_recvpage(con->sock, page, page_offset, length); |
1828 | if (ret <= 0) | 1843 | if (ret <= 0) |
1829 | return ret; | 1844 | return ret; |
1830 | 1845 | ||
1831 | in_msg_pos_next(con, left, ret); | 1846 | if (do_datacrc) { |
1847 | void *kaddr; | ||
1848 | void *base; | ||
1849 | |||
1850 | kaddr = kmap(page); | ||
1851 | BUG_ON(!kaddr); | ||
1852 | base = kaddr + page_offset; | ||
1853 | con->in_data_crc = crc32c(con->in_data_crc, base, ret); | ||
1854 | kunmap(page); | ||
1855 | } | ||
1856 | |||
1857 | in_msg_pos_next(con, length, ret); | ||
1832 | 1858 | ||
1833 | return ret; | 1859 | return ret; |
1834 | } | 1860 | } |
@@ -1841,29 +1867,37 @@ static int read_partial_message_bio(struct ceph_connection *con, | |||
1841 | struct ceph_msg_pos *msg_pos = &con->in_msg_pos; | 1867 | struct ceph_msg_pos *msg_pos = &con->in_msg_pos; |
1842 | struct bio_vec *bv; | 1868 | struct bio_vec *bv; |
1843 | struct page *page; | 1869 | struct page *page; |
1844 | void *p; | 1870 | size_t page_offset; |
1845 | int ret, left; | 1871 | size_t length; |
1872 | unsigned int left; | ||
1873 | int ret; | ||
1846 | 1874 | ||
1847 | BUG_ON(!msg); | 1875 | BUG_ON(!msg); |
1848 | BUG_ON(!msg->bio_iter); | 1876 | BUG_ON(!msg->bio_iter); |
1849 | bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg); | 1877 | bv = bio_iovec_idx(msg->bio_iter, msg->bio_seg); |
1850 | |||
1851 | left = min((int)(data_len - msg_pos->data_pos), | ||
1852 | (int)(bv->bv_len - msg_pos->page_pos)); | ||
1853 | |||
1854 | page = bv->bv_page; | 1878 | page = bv->bv_page; |
1855 | p = kmap(page) + bv->bv_offset; | 1879 | page_offset = bv->bv_offset + msg_pos->page_pos; |
1880 | BUG_ON(msg_pos->data_pos >= data_len); | ||
1881 | left = data_len - msg_pos->data_pos; | ||
1882 | BUG_ON(msg_pos->page_pos >= bv->bv_len); | ||
1883 | length = min_t(unsigned int, bv->bv_len - msg_pos->page_pos, left); | ||
1856 | 1884 | ||
1857 | ret = ceph_tcp_recvmsg(con->sock, p + msg_pos->page_pos, left); | 1885 | ret = ceph_tcp_recvpage(con->sock, page, page_offset, length); |
1858 | if (ret > 0 && do_datacrc) | ||
1859 | con->in_data_crc = | ||
1860 | crc32c(con->in_data_crc, | ||
1861 | p + msg_pos->page_pos, ret); | ||
1862 | kunmap(page); | ||
1863 | if (ret <= 0) | 1886 | if (ret <= 0) |
1864 | return ret; | 1887 | return ret; |
1865 | 1888 | ||
1866 | in_msg_pos_next(con, left, ret); | 1889 | if (do_datacrc) { |
1890 | void *kaddr; | ||
1891 | void *base; | ||
1892 | |||
1893 | kaddr = kmap(page); | ||
1894 | BUG_ON(!kaddr); | ||
1895 | base = kaddr + page_offset; | ||
1896 | con->in_data_crc = crc32c(con->in_data_crc, base, ret); | ||
1897 | kunmap(page); | ||
1898 | } | ||
1899 | |||
1900 | in_msg_pos_next(con, length, ret); | ||
1867 | 1901 | ||
1868 | return ret; | 1902 | return ret; |
1869 | } | 1903 | } |