aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osd_client.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-02-14 13:16:43 -0500
committerSage Weil <sage@inktank.com>2013-05-02 00:16:27 -0400
commit0fff87ec798abdb4a99f01cbb0197266bb68c5dc (patch)
tree33c853319e28ed9dd20835c1f3f066be404b50a1 /net/ceph/osd_client.c
parent2ac2b7a6d4976bd6b5dc0751aa77d12d48d3ac4c (diff)
libceph: separate read and write data
An osd request defines information about where data to be read should be placed as well as where data to write comes from. Currently these are represented by common fields. Keep information about data for writing separate from data to be read by splitting these into data_in and data_out fields. This is the key patch in this whole series, in that it actually identifies which osd requests generate outgoing data and which generate incoming data. It's less obvious (currently) that an osd CALL op generates both outgoing and incoming data; that's the focus of some upcoming work. This resolves: http://tracker.ceph.com/issues/4127 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'net/ceph/osd_client.c')
-rw-r--r--net/ceph/osd_client.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 591e1b0cccbe..f9cf44504484 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -122,10 +122,16 @@ void ceph_osdc_release_request(struct kref *kref)
122 } 122 }
123 if (req->r_reply) 123 if (req->r_reply)
124 ceph_msg_put(req->r_reply); 124 ceph_msg_put(req->r_reply);
125 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES && 125
126 req->r_data.own_pages) 126 if (req->r_data_in.type == CEPH_OSD_DATA_TYPE_PAGES &&
127 ceph_release_page_vector(req->r_data.pages, 127 req->r_data_in.own_pages)
128 req->r_data.num_pages); 128 ceph_release_page_vector(req->r_data_in.pages,
129 req->r_data_in.num_pages);
130 if (req->r_data_out.type == CEPH_OSD_DATA_TYPE_PAGES &&
131 req->r_data_out.own_pages)
132 ceph_release_page_vector(req->r_data_out.pages,
133 req->r_data_out.num_pages);
134
129 ceph_put_snap_context(req->r_snapc); 135 ceph_put_snap_context(req->r_snapc);
130 ceph_pagelist_release(&req->r_trail); 136 ceph_pagelist_release(&req->r_trail);
131 if (req->r_mempool) 137 if (req->r_mempool)
@@ -189,7 +195,8 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
189 } 195 }
190 req->r_reply = msg; 196 req->r_reply = msg;
191 197
192 req->r_data.type = CEPH_OSD_DATA_TYPE_NONE; 198 req->r_data_in.type = CEPH_OSD_DATA_TYPE_NONE;
199 req->r_data_out.type = CEPH_OSD_DATA_TYPE_NONE;
193 ceph_pagelist_init(&req->r_trail); 200 ceph_pagelist_init(&req->r_trail);
194 201
195 /* create request message; allow space for oid */ 202 /* create request message; allow space for oid */
@@ -1740,17 +1747,21 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1740 bool nofail) 1747 bool nofail)
1741{ 1748{
1742 int rc = 0; 1749 int rc = 0;
1750 struct ceph_osd_data *osd_data;
1751
1752 /* Set up outgoing data */
1743 1753
1744 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) { 1754 osd_data = &req->r_data_out;
1745 req->r_request->pages = req->r_data.pages; 1755 if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
1746 req->r_request->page_count = req->r_data.num_pages; 1756 req->r_request->pages = osd_data->pages;
1747 req->r_request->page_alignment = req->r_data.alignment; 1757 req->r_request->page_count = osd_data->num_pages;
1758 req->r_request->page_alignment = osd_data->alignment;
1748#ifdef CONFIG_BLOCK 1759#ifdef CONFIG_BLOCK
1749 } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) { 1760 } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) {
1750 req->r_request->bio = req->r_data.bio; 1761 req->r_request->bio = osd_data->bio;
1751#endif 1762#endif
1752 } else { 1763 } else {
1753 pr_err("unknown request data type %d\n", req->r_data.type); 1764 BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_NONE);
1754 } 1765 }
1755 req->r_request->trail = &req->r_trail; 1766 req->r_request->trail = &req->r_trail;
1756 1767
@@ -1939,6 +1950,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1939 struct page **pages, int num_pages, int page_align) 1950 struct page **pages, int num_pages, int page_align)
1940{ 1951{
1941 struct ceph_osd_request *req; 1952 struct ceph_osd_request *req;
1953 struct ceph_osd_data *osd_data;
1942 int rc = 0; 1954 int rc = 0;
1943 1955
1944 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, 1956 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
@@ -1951,13 +1963,15 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1951 return PTR_ERR(req); 1963 return PTR_ERR(req);
1952 1964
1953 /* it may be a short read due to an object boundary */ 1965 /* it may be a short read due to an object boundary */
1954 req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; 1966
1955 req->r_data.pages = pages; 1967 osd_data = &req->r_data_in;
1956 req->r_data.num_pages = calc_pages_for(page_align, *plen); 1968 osd_data->type = CEPH_OSD_DATA_TYPE_PAGES;
1957 req->r_data.alignment = page_align; 1969 osd_data->pages = pages;
1970 osd_data->num_pages = calc_pages_for(page_align, *plen);
1971 osd_data->alignment = page_align;
1958 1972
1959 dout("readpages final extent is %llu~%llu (%d pages align %d)\n", 1973 dout("readpages final extent is %llu~%llu (%d pages align %d)\n",
1960 off, *plen, req->r_data.num_pages, page_align); 1974 off, *plen, osd_data->num_pages, page_align);
1961 1975
1962 rc = ceph_osdc_start_request(osdc, req, false); 1976 rc = ceph_osdc_start_request(osdc, req, false);
1963 if (!rc) 1977 if (!rc)
@@ -1981,6 +1995,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1981 struct page **pages, int num_pages) 1995 struct page **pages, int num_pages)
1982{ 1996{
1983 struct ceph_osd_request *req; 1997 struct ceph_osd_request *req;
1998 struct ceph_osd_data *osd_data;
1984 int rc = 0; 1999 int rc = 0;
1985 int page_align = off & ~PAGE_MASK; 2000 int page_align = off & ~PAGE_MASK;
1986 2001
@@ -1995,11 +2010,13 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1995 return PTR_ERR(req); 2010 return PTR_ERR(req);
1996 2011
1997 /* it may be a short write due to an object boundary */ 2012 /* it may be a short write due to an object boundary */
1998 req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES; 2013 osd_data = &req->r_data_out;
1999 req->r_data.pages = pages; 2014 osd_data->type = CEPH_OSD_DATA_TYPE_PAGES;
2000 req->r_data.num_pages = calc_pages_for(page_align, len); 2015 osd_data->pages = pages;
2001 req->r_data.alignment = page_align; 2016 osd_data->num_pages = calc_pages_for(page_align, len);
2002 dout("writepages %llu~%llu (%d pages)\n", off, len, req->r_data.num_pages); 2017 osd_data->alignment = page_align;
2018 dout("writepages %llu~%llu (%d pages)\n", off, len,
2019 osd_data->num_pages);
2003 2020
2004 rc = ceph_osdc_start_request(osdc, req, true); 2021 rc = ceph_osdc_start_request(osdc, req, true);
2005 if (!rc) 2022 if (!rc)
@@ -2092,28 +2109,30 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
2092 m = ceph_msg_get(req->r_reply); 2109 m = ceph_msg_get(req->r_reply);
2093 2110
2094 if (data_len > 0) { 2111 if (data_len > 0) {
2095 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) { 2112 struct ceph_osd_data *osd_data = &req->r_data_in;
2113
2114 if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
2096 int want; 2115 int want;
2097 2116
2098 want = calc_pages_for(req->r_data.alignment, data_len); 2117 want = calc_pages_for(osd_data->alignment, data_len);
2099 if (req->r_data.pages && 2118 if (osd_data->pages &&
2100 unlikely(req->r_data.num_pages < want)) { 2119 unlikely(osd_data->num_pages < want)) {
2101 2120
2102 pr_warning("tid %lld reply has %d bytes %d " 2121 pr_warning("tid %lld reply has %d bytes %d "
2103 "pages, we had only %d pages ready\n", 2122 "pages, we had only %d pages ready\n",
2104 tid, data_len, want, 2123 tid, data_len, want,
2105 req->r_data.num_pages); 2124 osd_data->num_pages);
2106 *skip = 1; 2125 *skip = 1;
2107 ceph_msg_put(m); 2126 ceph_msg_put(m);
2108 m = NULL; 2127 m = NULL;
2109 goto out; 2128 goto out;
2110 } 2129 }
2111 m->pages = req->r_data.pages; 2130 m->pages = osd_data->pages;
2112 m->page_count = req->r_data.num_pages; 2131 m->page_count = osd_data->num_pages;
2113 m->page_alignment = req->r_data.alignment; 2132 m->page_alignment = osd_data->alignment;
2114#ifdef CONFIG_BLOCK 2133#ifdef CONFIG_BLOCK
2115 } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) { 2134 } else if (osd_data->type == CEPH_OSD_DATA_TYPE_BIO) {
2116 m->bio = req->r_data.bio; 2135 m->bio = osd_data->bio;
2117#endif 2136#endif
2118 } 2137 }
2119 } 2138 }