aboutsummaryrefslogtreecommitdiffstats
path: root/net
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:25 -0400
commit2ac2b7a6d4976bd6b5dc0751aa77d12d48d3ac4c (patch)
treeaf95ff579ab1719871e8678ef530db46514c0eb7 /net
parent2794a82a11cfeae0890741b18b0049ddb55ce646 (diff)
libceph: distinguish page and bio requests
An osd request uses either pages or a bio list for its data. Use a union to record information about the two, and add a data type tag to select between them. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/osd_client.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 1f8c7a7c203b..591e1b0cccbe 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -122,7 +122,8 @@ 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.own_pages) 125 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES &&
126 req->r_data.own_pages)
126 ceph_release_page_vector(req->r_data.pages, 127 ceph_release_page_vector(req->r_data.pages,
127 req->r_data.num_pages); 128 req->r_data.num_pages);
128 ceph_put_snap_context(req->r_snapc); 129 ceph_put_snap_context(req->r_snapc);
@@ -188,6 +189,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
188 } 189 }
189 req->r_reply = msg; 190 req->r_reply = msg;
190 191
192 req->r_data.type = CEPH_OSD_DATA_TYPE_NONE;
191 ceph_pagelist_init(&req->r_trail); 193 ceph_pagelist_init(&req->r_trail);
192 194
193 /* create request message; allow space for oid */ 195 /* create request message; allow space for oid */
@@ -1739,12 +1741,17 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1739{ 1741{
1740 int rc = 0; 1742 int rc = 0;
1741 1743
1742 req->r_request->pages = req->r_data.pages; 1744 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) {
1743 req->r_request->page_count = req->r_data.num_pages; 1745 req->r_request->pages = req->r_data.pages;
1744 req->r_request->page_alignment = req->r_data.alignment; 1746 req->r_request->page_count = req->r_data.num_pages;
1747 req->r_request->page_alignment = req->r_data.alignment;
1745#ifdef CONFIG_BLOCK 1748#ifdef CONFIG_BLOCK
1746 req->r_request->bio = req->r_data.bio; 1749 } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) {
1750 req->r_request->bio = req->r_data.bio;
1747#endif 1751#endif
1752 } else {
1753 pr_err("unknown request data type %d\n", req->r_data.type);
1754 }
1748 req->r_request->trail = &req->r_trail; 1755 req->r_request->trail = &req->r_trail;
1749 1756
1750 register_request(osdc, req); 1757 register_request(osdc, req);
@@ -1944,6 +1951,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1944 return PTR_ERR(req); 1951 return PTR_ERR(req);
1945 1952
1946 /* it may be a short read due to an object boundary */ 1953 /* it may be a short read due to an object boundary */
1954 req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES;
1947 req->r_data.pages = pages; 1955 req->r_data.pages = pages;
1948 req->r_data.num_pages = calc_pages_for(page_align, *plen); 1956 req->r_data.num_pages = calc_pages_for(page_align, *plen);
1949 req->r_data.alignment = page_align; 1957 req->r_data.alignment = page_align;
@@ -1987,6 +1995,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1987 return PTR_ERR(req); 1995 return PTR_ERR(req);
1988 1996
1989 /* it may be a short write due to an object boundary */ 1997 /* it may be a short write due to an object boundary */
1998 req->r_data.type = CEPH_OSD_DATA_TYPE_PAGES;
1990 req->r_data.pages = pages; 1999 req->r_data.pages = pages;
1991 req->r_data.num_pages = calc_pages_for(page_align, len); 2000 req->r_data.num_pages = calc_pages_for(page_align, len);
1992 req->r_data.alignment = page_align; 2001 req->r_data.alignment = page_align;
@@ -2083,23 +2092,30 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
2083 m = ceph_msg_get(req->r_reply); 2092 m = ceph_msg_get(req->r_reply);
2084 2093
2085 if (data_len > 0) { 2094 if (data_len > 0) {
2086 int want = calc_pages_for(req->r_data.alignment, data_len); 2095 if (req->r_data.type == CEPH_OSD_DATA_TYPE_PAGES) {
2087 2096 int want;
2088 if (req->r_data.pages && unlikely(req->r_data.num_pages < want)) { 2097
2089 pr_warning("tid %lld reply has %d bytes %d pages, we" 2098 want = calc_pages_for(req->r_data.alignment, data_len);
2090 " had only %d pages ready\n", tid, data_len, 2099 if (req->r_data.pages &&
2091 want, req->r_data.num_pages); 2100 unlikely(req->r_data.num_pages < want)) {
2092 *skip = 1; 2101
2093 ceph_msg_put(m); 2102 pr_warning("tid %lld reply has %d bytes %d "
2094 m = NULL; 2103 "pages, we had only %d pages ready\n",
2095 goto out; 2104 tid, data_len, want,
2096 } 2105 req->r_data.num_pages);
2097 m->pages = req->r_data.pages; 2106 *skip = 1;
2098 m->page_count = req->r_data.num_pages; 2107 ceph_msg_put(m);
2099 m->page_alignment = req->r_data.alignment; 2108 m = NULL;
2109 goto out;
2110 }
2111 m->pages = req->r_data.pages;
2112 m->page_count = req->r_data.num_pages;
2113 m->page_alignment = req->r_data.alignment;
2100#ifdef CONFIG_BLOCK 2114#ifdef CONFIG_BLOCK
2101 m->bio = req->r_data.bio; 2115 } else if (req->r_data.type == CEPH_OSD_DATA_TYPE_BIO) {
2116 m->bio = req->r_data.bio;
2102#endif 2117#endif
2118 }
2103 } 2119 }
2104 *skip = 0; 2120 *skip = 0;
2105 req->r_con_filling_msg = con->ops->get(con); 2121 req->r_con_filling_msg = con->ops->get(con);