diff options
author | Alex Elder <elder@inktank.com> | 2013-04-05 02:27:12 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:18:23 -0400 |
commit | a4ce40a9a7c1053ac2a41cf64255e44e356e5522 (patch) | |
tree | de1aeb42625f19f6cfe8806db333ec853de0f5b7 | |
parent | 39b44cbe86db42e70693787b2ede81c309925d0b (diff) |
libceph: combine initializing and setting osd data
This ends up being a rather large patch but what it's doing is
somewhat straightforward.
Basically, this is replacing two calls with one. The first of the
two calls is initializing a struct ceph_osd_data with data (either a
page array, a page list, or a bio list); the second is setting an
osd request op so it associates that data with one of the op's
parameters. In place of those two will be a single function that
initializes the op directly.
That means we sort of fan out a set of the needed functions:
- extent ops with pages data
- extent ops with pagelist data
- extent ops with bio list data
and
- class ops with page data for receiving a response
We also have define another one, but it's only used internally:
- class ops with pagelist data for request parameters
Note that we *still* haven't gotten rid of the osd request's
r_data_in and r_data_out fields. All the osd ops refer to them for
their data. For now, these data fields are pointers assigned to the
appropriate r_data_* field when these new functions are called.
Signed-off-by: Alex Elder <elder@inktank.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
-rw-r--r-- | drivers/block/rbd.c | 20 | ||||
-rw-r--r-- | fs/ceph/addr.c | 12 | ||||
-rw-r--r-- | fs/ceph/file.c | 3 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 43 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 155 |
5 files changed, 161 insertions, 72 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index db29783436c8..6f7a52cf75c7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1592,7 +1592,6 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, | |||
1592 | rbd_assert(resid > 0); | 1592 | rbd_assert(resid > 0); |
1593 | while (resid) { | 1593 | while (resid) { |
1594 | struct ceph_osd_request *osd_req; | 1594 | struct ceph_osd_request *osd_req; |
1595 | struct ceph_osd_data *osd_data; | ||
1596 | const char *object_name; | 1595 | const char *object_name; |
1597 | unsigned int clone_size; | 1596 | unsigned int clone_size; |
1598 | u64 offset; | 1597 | u64 offset; |
@@ -1625,13 +1624,10 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, | |||
1625 | obj_request->osd_req = osd_req; | 1624 | obj_request->osd_req = osd_req; |
1626 | obj_request->callback = rbd_img_obj_callback; | 1625 | obj_request->callback = rbd_img_obj_callback; |
1627 | 1626 | ||
1628 | osd_data = write_request ? &osd_req->r_data_out | ||
1629 | : &osd_req->r_data_in; | ||
1630 | osd_req_op_extent_init(osd_req, 0, opcode, offset, length, | 1627 | osd_req_op_extent_init(osd_req, 0, opcode, offset, length, |
1631 | 0, 0); | 1628 | 0, 0); |
1632 | ceph_osd_data_bio_init(osd_data, obj_request->bio_list, | 1629 | osd_req_op_extent_osd_data_bio(osd_req, 0, write_request, |
1633 | obj_request->length); | 1630 | obj_request->bio_list, obj_request->length); |
1634 | osd_req_op_extent_osd_data(osd_req, 0, osd_data); | ||
1635 | rbd_osd_req_format(obj_request, write_request); | 1631 | rbd_osd_req_format(obj_request, write_request); |
1636 | 1632 | ||
1637 | rbd_img_obj_request_add(img_request, obj_request); | 1633 | rbd_img_obj_request_add(img_request, obj_request); |
@@ -1821,7 +1817,6 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, | |||
1821 | { | 1817 | { |
1822 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; | 1818 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; |
1823 | struct rbd_obj_request *obj_request; | 1819 | struct rbd_obj_request *obj_request; |
1824 | struct ceph_osd_data *osd_data; | ||
1825 | struct page **pages; | 1820 | struct page **pages; |
1826 | u32 page_count; | 1821 | u32 page_count; |
1827 | int ret; | 1822 | int ret; |
@@ -1851,13 +1846,12 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, | |||
1851 | if (!obj_request->osd_req) | 1846 | if (!obj_request->osd_req) |
1852 | goto out; | 1847 | goto out; |
1853 | 1848 | ||
1854 | osd_data = &obj_request->osd_req->r_data_in; | ||
1855 | osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, | 1849 | osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, |
1856 | class_name, method_name, | 1850 | class_name, method_name, |
1857 | outbound, outbound_size); | 1851 | outbound, outbound_size); |
1858 | ceph_osd_data_pages_init(osd_data, obj_request->pages, inbound_size, | 1852 | osd_req_op_cls_response_data_pages(obj_request->osd_req, 0, |
1853 | obj_request->pages, inbound_size, | ||
1859 | 0, false, false); | 1854 | 0, false, false); |
1860 | osd_req_op_cls_response_data(obj_request->osd_req, 0, osd_data); | ||
1861 | rbd_osd_req_format(obj_request, false); | 1855 | rbd_osd_req_format(obj_request, false); |
1862 | 1856 | ||
1863 | ret = rbd_obj_request_submit(osdc, obj_request); | 1857 | ret = rbd_obj_request_submit(osdc, obj_request); |
@@ -2037,7 +2031,6 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, | |||
2037 | { | 2031 | { |
2038 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; | 2032 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; |
2039 | struct rbd_obj_request *obj_request; | 2033 | struct rbd_obj_request *obj_request; |
2040 | struct ceph_osd_data *osd_data; | ||
2041 | struct page **pages = NULL; | 2034 | struct page **pages = NULL; |
2042 | u32 page_count; | 2035 | u32 page_count; |
2043 | size_t size; | 2036 | size_t size; |
@@ -2061,14 +2054,13 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, | |||
2061 | if (!obj_request->osd_req) | 2054 | if (!obj_request->osd_req) |
2062 | goto out; | 2055 | goto out; |
2063 | 2056 | ||
2064 | osd_data = &obj_request->osd_req->r_data_in; | ||
2065 | osd_req_op_extent_init(obj_request->osd_req, 0, CEPH_OSD_OP_READ, | 2057 | osd_req_op_extent_init(obj_request->osd_req, 0, CEPH_OSD_OP_READ, |
2066 | offset, length, 0, 0); | 2058 | offset, length, 0, 0); |
2067 | ceph_osd_data_pages_init(osd_data, obj_request->pages, | 2059 | osd_req_op_extent_osd_data_pages(obj_request->osd_req, 0, false, |
2060 | obj_request->pages, | ||
2068 | obj_request->length, | 2061 | obj_request->length, |
2069 | obj_request->offset & ~PAGE_MASK, | 2062 | obj_request->offset & ~PAGE_MASK, |
2070 | false, false); | 2063 | false, false); |
2071 | osd_req_op_extent_osd_data(obj_request->osd_req, 0, osd_data); | ||
2072 | rbd_osd_req_format(obj_request, false); | 2064 | rbd_osd_req_format(obj_request, false); |
2073 | 2065 | ||
2074 | ret = rbd_obj_request_submit(osdc, obj_request); | 2066 | ret = rbd_obj_request_submit(osdc, obj_request); |
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index cc57104a7266..27d62070a8e9 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -245,7 +245,7 @@ static void finish_read(struct ceph_osd_request *req, struct ceph_msg *msg) | |||
245 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); | 245 | dout("finish_read %p req %p rc %d bytes %d\n", inode, req, rc, bytes); |
246 | 246 | ||
247 | /* unlock all pages, zeroing any data we didn't read */ | 247 | /* unlock all pages, zeroing any data we didn't read */ |
248 | osd_data = &req->r_data_in; | 248 | osd_data = osd_req_op_extent_osd_data(req, 0, false); |
249 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES); | 249 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES); |
250 | num_pages = calc_pages_for((u64)osd_data->alignment, | 250 | num_pages = calc_pages_for((u64)osd_data->alignment, |
251 | (u64)osd_data->length); | 251 | (u64)osd_data->length); |
@@ -343,8 +343,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max) | |||
343 | } | 343 | } |
344 | pages[i] = page; | 344 | pages[i] = page; |
345 | } | 345 | } |
346 | BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_in); | 346 | osd_req_op_extent_osd_data_pages(req, 0, false, pages, len, 0, |
347 | ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages, len, 0, | ||
348 | false, false); | 347 | false, false); |
349 | req->r_callback = finish_read; | 348 | req->r_callback = finish_read; |
350 | req->r_inode = inode; | 349 | req->r_inode = inode; |
@@ -572,7 +571,7 @@ static void writepages_finish(struct ceph_osd_request *req, | |||
572 | long writeback_stat; | 571 | long writeback_stat; |
573 | unsigned issued = ceph_caps_issued(ci); | 572 | unsigned issued = ceph_caps_issued(ci); |
574 | 573 | ||
575 | osd_data = &req->r_data_out; | 574 | osd_data = osd_req_op_extent_osd_data(req, 0, true); |
576 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES); | 575 | BUG_ON(osd_data->type != CEPH_OSD_DATA_TYPE_PAGES); |
577 | num_pages = calc_pages_for((u64)osd_data->alignment, | 576 | num_pages = calc_pages_for((u64)osd_data->alignment, |
578 | (u64)osd_data->length); | 577 | (u64)osd_data->length); |
@@ -917,9 +916,8 @@ get_more_pages: | |||
917 | dout("writepages got %d pages at %llu~%llu\n", | 916 | dout("writepages got %d pages at %llu~%llu\n", |
918 | locked_pages, offset, len); | 917 | locked_pages, offset, len); |
919 | 918 | ||
920 | BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_out); | 919 | osd_req_op_extent_osd_data_pages(req, 0, true, pages, len, 0, |
921 | ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages, | 920 | !!pool, false); |
922 | len, 0, !!pool, false); | ||
923 | 921 | ||
924 | pages = NULL; /* request message now owns the pages array */ | 922 | pages = NULL; /* request message now owns the pages array */ |
925 | pool = NULL; | 923 | pool = NULL; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index cddc10fd7cf9..0f9c4095614b 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -574,8 +574,7 @@ more: | |||
574 | own_pages = true; | 574 | own_pages = true; |
575 | } | 575 | } |
576 | } | 576 | } |
577 | BUG_ON(req->r_ops[0].extent.osd_data != &req->r_data_out); | 577 | osd_req_op_extent_osd_data_pages(req, 0, true, pages, len, |
578 | ceph_osd_data_pages_init(req->r_ops[0].extent.osd_data, pages, len, | ||
579 | page_align, false, own_pages); | 578 | page_align, false, own_pages); |
580 | 579 | ||
581 | /* BUG_ON(vino.snap != CEPH_NOSNAP); */ | 580 | /* BUG_ON(vino.snap != CEPH_NOSNAP); */ |
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 71c41575646d..f8a00b48e550 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h | |||
@@ -240,17 +240,39 @@ extern void osd_req_op_extent_init(struct ceph_osd_request *osd_req, | |||
240 | u64 truncate_size, u32 truncate_seq); | 240 | u64 truncate_size, u32 truncate_seq); |
241 | extern void osd_req_op_extent_update(struct ceph_osd_request *osd_req, | 241 | extern void osd_req_op_extent_update(struct ceph_osd_request *osd_req, |
242 | unsigned int which, u64 length); | 242 | unsigned int which, u64 length); |
243 | extern void osd_req_op_extent_osd_data(struct ceph_osd_request *osd_req, | 243 | |
244 | extern struct ceph_osd_data *osd_req_op_extent_osd_data( | ||
245 | struct ceph_osd_request *osd_req, | ||
246 | unsigned int which, bool write_request); | ||
247 | extern struct ceph_osd_data *osd_req_op_cls_response_data( | ||
248 | struct ceph_osd_request *osd_req, | ||
249 | unsigned int which); | ||
250 | |||
251 | extern void osd_req_op_extent_osd_data_pages(struct ceph_osd_request *, | ||
252 | unsigned int which, bool write_request, | ||
253 | struct page **pages, u64 length, | ||
254 | u32 alignment, bool pages_from_pool, | ||
255 | bool own_pages); | ||
256 | extern void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *, | ||
257 | unsigned int which, bool write_request, | ||
258 | struct ceph_pagelist *pagelist); | ||
259 | #ifdef CONFIG_BLOCK | ||
260 | extern void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *, | ||
261 | unsigned int which, bool write_request, | ||
262 | struct bio *bio, size_t bio_length); | ||
263 | #endif /* CONFIG_BLOCK */ | ||
264 | |||
265 | extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, | ||
244 | unsigned int which, | 266 | unsigned int which, |
245 | struct ceph_osd_data *osd_data); | 267 | struct page **pages, u64 length, |
268 | u32 alignment, bool pages_from_pool, | ||
269 | bool own_pages); | ||
270 | |||
246 | extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, | 271 | extern void osd_req_op_cls_init(struct ceph_osd_request *osd_req, |
247 | unsigned int which, u16 opcode, | 272 | unsigned int which, u16 opcode, |
248 | const char *class, const char *method, | 273 | const char *class, const char *method, |
249 | const void *request_data, | 274 | const void *request_data, |
250 | size_t request_data_size); | 275 | size_t request_data_size); |
251 | extern void osd_req_op_cls_response_data(struct ceph_osd_request *osd_req, | ||
252 | unsigned int which, | ||
253 | struct ceph_osd_data *response_data); | ||
254 | extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req, | 276 | extern void osd_req_op_watch_init(struct ceph_osd_request *osd_req, |
255 | unsigned int which, u16 opcode, | 277 | unsigned int which, u16 opcode, |
256 | u64 cookie, u64 version, int flag); | 278 | u64 cookie, u64 version, int flag); |
@@ -290,17 +312,6 @@ static inline void ceph_osdc_put_request(struct ceph_osd_request *req) | |||
290 | kref_put(&req->r_kref, ceph_osdc_release_request); | 312 | kref_put(&req->r_kref, ceph_osdc_release_request); |
291 | } | 313 | } |
292 | 314 | ||
293 | extern void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, | ||
294 | struct page **pages, u64 length, | ||
295 | u32 alignment, bool pages_from_pool, | ||
296 | bool own_pages); | ||
297 | extern void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data, | ||
298 | struct ceph_pagelist *pagelist); | ||
299 | #ifdef CONFIG_BLOCK | ||
300 | extern void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data, | ||
301 | struct bio *bio, size_t bio_length); | ||
302 | #endif /* CONFIG_BLOCK */ | ||
303 | |||
304 | extern int ceph_osdc_start_request(struct ceph_osd_client *osdc, | 315 | extern int ceph_osdc_start_request(struct ceph_osd_client *osdc, |
305 | struct ceph_osd_request *req, | 316 | struct ceph_osd_request *req, |
306 | bool nofail); | 317 | bool nofail); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 932b8af8b8ee..86cb52404f17 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | #include <linux/ceph/ceph_debug.h> | 2 | #include <linux/ceph/ceph_debug.h> |
2 | 3 | ||
3 | #include <linux/module.h> | 4 | #include <linux/module.h> |
@@ -85,7 +86,7 @@ static void ceph_osd_data_init(struct ceph_osd_data *osd_data) | |||
85 | osd_data->type = CEPH_OSD_DATA_TYPE_NONE; | 86 | osd_data->type = CEPH_OSD_DATA_TYPE_NONE; |
86 | } | 87 | } |
87 | 88 | ||
88 | void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, | 89 | static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, |
89 | struct page **pages, u64 length, u32 alignment, | 90 | struct page **pages, u64 length, u32 alignment, |
90 | bool pages_from_pool, bool own_pages) | 91 | bool pages_from_pool, bool own_pages) |
91 | { | 92 | { |
@@ -96,27 +97,131 @@ void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, | |||
96 | osd_data->pages_from_pool = pages_from_pool; | 97 | osd_data->pages_from_pool = pages_from_pool; |
97 | osd_data->own_pages = own_pages; | 98 | osd_data->own_pages = own_pages; |
98 | } | 99 | } |
99 | EXPORT_SYMBOL(ceph_osd_data_pages_init); | ||
100 | 100 | ||
101 | void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data, | 101 | static void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data, |
102 | struct ceph_pagelist *pagelist) | 102 | struct ceph_pagelist *pagelist) |
103 | { | 103 | { |
104 | osd_data->type = CEPH_OSD_DATA_TYPE_PAGELIST; | 104 | osd_data->type = CEPH_OSD_DATA_TYPE_PAGELIST; |
105 | osd_data->pagelist = pagelist; | 105 | osd_data->pagelist = pagelist; |
106 | } | 106 | } |
107 | EXPORT_SYMBOL(ceph_osd_data_pagelist_init); | ||
108 | 107 | ||
109 | #ifdef CONFIG_BLOCK | 108 | #ifdef CONFIG_BLOCK |
110 | void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data, | 109 | static void ceph_osd_data_bio_init(struct ceph_osd_data *osd_data, |
111 | struct bio *bio, size_t bio_length) | 110 | struct bio *bio, size_t bio_length) |
112 | { | 111 | { |
113 | osd_data->type = CEPH_OSD_DATA_TYPE_BIO; | 112 | osd_data->type = CEPH_OSD_DATA_TYPE_BIO; |
114 | osd_data->bio = bio; | 113 | osd_data->bio = bio; |
115 | osd_data->bio_length = bio_length; | 114 | osd_data->bio_length = bio_length; |
116 | } | 115 | } |
117 | EXPORT_SYMBOL(ceph_osd_data_bio_init); | ||
118 | #endif /* CONFIG_BLOCK */ | 116 | #endif /* CONFIG_BLOCK */ |
119 | 117 | ||
118 | struct ceph_osd_data * | ||
119 | osd_req_op_extent_osd_data(struct ceph_osd_request *osd_req, | ||
120 | unsigned int which, bool write_request) | ||
121 | { | ||
122 | BUG_ON(which >= osd_req->r_num_ops); | ||
123 | |||
124 | /* return &osd_req->r_ops[which].extent.osd_data; */ | ||
125 | return write_request ? &osd_req->r_data_out : &osd_req->r_data_in; | ||
126 | } | ||
127 | EXPORT_SYMBOL(osd_req_op_extent_osd_data); | ||
128 | |||
129 | struct ceph_osd_data * | ||
130 | osd_req_op_cls_request_info(struct ceph_osd_request *osd_req, | ||
131 | unsigned int which) | ||
132 | { | ||
133 | BUG_ON(which >= osd_req->r_num_ops); | ||
134 | |||
135 | /* return &osd_req->r_ops[which].cls.request_info; */ | ||
136 | return &osd_req->r_data_out; /* Request data is outgoing */ | ||
137 | } | ||
138 | EXPORT_SYMBOL(osd_req_op_cls_request_info); /* ??? */ | ||
139 | |||
140 | struct ceph_osd_data * | ||
141 | osd_req_op_cls_response_data(struct ceph_osd_request *osd_req, | ||
142 | unsigned int which) | ||
143 | { | ||
144 | BUG_ON(which >= osd_req->r_num_ops); | ||
145 | |||
146 | /* return &osd_req->r_ops[which].cls.response_data; */ | ||
147 | return &osd_req->r_data_in; /* Response data is incoming */ | ||
148 | } | ||
149 | EXPORT_SYMBOL(osd_req_op_cls_response_data); /* ??? */ | ||
150 | |||
151 | void osd_req_op_extent_osd_data_pages(struct ceph_osd_request *osd_req, | ||
152 | unsigned int which, bool write_request, | ||
153 | struct page **pages, u64 length, u32 alignment, | ||
154 | bool pages_from_pool, bool own_pages) | ||
155 | { | ||
156 | struct ceph_osd_data *osd_data; | ||
157 | |||
158 | osd_data = osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
159 | ceph_osd_data_pages_init(osd_data, pages, length, alignment, | ||
160 | pages_from_pool, own_pages); | ||
161 | |||
162 | osd_req->r_ops[which].extent.osd_data = | ||
163 | osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
164 | } | ||
165 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_pages); | ||
166 | |||
167 | void osd_req_op_extent_osd_data_pagelist(struct ceph_osd_request *osd_req, | ||
168 | unsigned int which, bool write_request, | ||
169 | struct ceph_pagelist *pagelist) | ||
170 | { | ||
171 | struct ceph_osd_data *osd_data; | ||
172 | |||
173 | osd_data = osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
174 | ceph_osd_data_pagelist_init(osd_data, pagelist); | ||
175 | |||
176 | osd_req->r_ops[which].extent.osd_data = | ||
177 | osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
178 | } | ||
179 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_pagelist); | ||
180 | |||
181 | #ifdef CONFIG_BLOCK | ||
182 | void osd_req_op_extent_osd_data_bio(struct ceph_osd_request *osd_req, | ||
183 | unsigned int which, bool write_request, | ||
184 | struct bio *bio, size_t bio_length) | ||
185 | { | ||
186 | struct ceph_osd_data *osd_data; | ||
187 | |||
188 | osd_data = osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
189 | ceph_osd_data_bio_init(osd_data, bio, bio_length); | ||
190 | |||
191 | osd_req->r_ops[which].extent.osd_data = | ||
192 | osd_req_op_extent_osd_data(osd_req, which, write_request); | ||
193 | } | ||
194 | EXPORT_SYMBOL(osd_req_op_extent_osd_data_bio); | ||
195 | #endif /* CONFIG_BLOCK */ | ||
196 | |||
197 | static void osd_req_op_cls_request_info_pagelist( | ||
198 | struct ceph_osd_request *osd_req, | ||
199 | unsigned int which, struct ceph_pagelist *pagelist) | ||
200 | { | ||
201 | struct ceph_osd_data *osd_data; | ||
202 | |||
203 | osd_data = osd_req_op_cls_request_info(osd_req, which); | ||
204 | ceph_osd_data_pagelist_init(osd_data, pagelist); | ||
205 | |||
206 | osd_req->r_ops[which].cls.request_info = | ||
207 | osd_req_op_cls_request_info(osd_req, which); | ||
208 | } | ||
209 | |||
210 | void osd_req_op_cls_response_data_pages(struct ceph_osd_request *osd_req, | ||
211 | unsigned int which, struct page **pages, u64 length, | ||
212 | u32 alignment, bool pages_from_pool, bool own_pages) | ||
213 | { | ||
214 | struct ceph_osd_data *osd_data; | ||
215 | |||
216 | osd_data = osd_req_op_cls_response_data(osd_req, which); | ||
217 | ceph_osd_data_pages_init(osd_data, pages, length, alignment, | ||
218 | pages_from_pool, own_pages); | ||
219 | |||
220 | osd_req->r_ops[which].cls.response_data = | ||
221 | osd_req_op_cls_response_data(osd_req, which); | ||
222 | } | ||
223 | EXPORT_SYMBOL(osd_req_op_cls_response_data_pages); | ||
224 | |||
120 | static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data) | 225 | static u64 ceph_osd_data_length(struct ceph_osd_data *osd_data) |
121 | { | 226 | { |
122 | switch (osd_data->type) { | 227 | switch (osd_data->type) { |
@@ -385,15 +490,6 @@ void osd_req_op_extent_update(struct ceph_osd_request *osd_req, | |||
385 | } | 490 | } |
386 | EXPORT_SYMBOL(osd_req_op_extent_update); | 491 | EXPORT_SYMBOL(osd_req_op_extent_update); |
387 | 492 | ||
388 | void osd_req_op_extent_osd_data(struct ceph_osd_request *osd_req, | ||
389 | unsigned int which, | ||
390 | struct ceph_osd_data *osd_data) | ||
391 | { | ||
392 | BUG_ON(which >= osd_req->r_num_ops); | ||
393 | osd_req->r_ops[which].extent.osd_data = osd_data; | ||
394 | } | ||
395 | EXPORT_SYMBOL(osd_req_op_extent_osd_data); | ||
396 | |||
397 | void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, | 493 | void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, |
398 | u16 opcode, const char *class, const char *method, | 494 | u16 opcode, const char *class, const char *method, |
399 | const void *request_data, size_t request_data_size) | 495 | const void *request_data, size_t request_data_size) |
@@ -429,22 +525,13 @@ void osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, | |||
429 | ceph_pagelist_append(pagelist, request_data, request_data_size); | 525 | ceph_pagelist_append(pagelist, request_data, request_data_size); |
430 | payload_len += request_data_size; | 526 | payload_len += request_data_size; |
431 | 527 | ||
432 | op->cls.request_info = &osd_req->r_data_out; | 528 | osd_req_op_cls_request_info_pagelist(osd_req, which, pagelist); |
433 | ceph_osd_data_pagelist_init(op->cls.request_info, pagelist); | ||
434 | 529 | ||
435 | op->cls.argc = 0; /* currently unused */ | 530 | op->cls.argc = 0; /* currently unused */ |
436 | 531 | ||
437 | op->payload_len = payload_len; | 532 | op->payload_len = payload_len; |
438 | } | 533 | } |
439 | EXPORT_SYMBOL(osd_req_op_cls_init); | 534 | EXPORT_SYMBOL(osd_req_op_cls_init); |
440 | void osd_req_op_cls_response_data(struct ceph_osd_request *osd_req, | ||
441 | unsigned int which, | ||
442 | struct ceph_osd_data *response_data) | ||
443 | { | ||
444 | BUG_ON(which >= osd_req->r_num_ops); | ||
445 | osd_req->r_ops[which].cls.response_data = response_data; | ||
446 | } | ||
447 | EXPORT_SYMBOL(osd_req_op_cls_response_data); | ||
448 | 535 | ||
449 | void osd_req_op_watch_init(struct ceph_osd_request *osd_req, | 536 | void osd_req_op_watch_init(struct ceph_osd_request *osd_req, |
450 | unsigned int which, u16 opcode, | 537 | unsigned int which, u16 opcode, |
@@ -547,7 +634,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
547 | bool use_mempool) | 634 | bool use_mempool) |
548 | { | 635 | { |
549 | struct ceph_osd_request *req; | 636 | struct ceph_osd_request *req; |
550 | struct ceph_osd_data *osd_data; | ||
551 | u64 objnum = 0; | 637 | u64 objnum = 0; |
552 | u64 objoff = 0; | 638 | u64 objoff = 0; |
553 | u64 objlen = 0; | 639 | u64 objlen = 0; |
@@ -561,8 +647,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
561 | GFP_NOFS); | 647 | GFP_NOFS); |
562 | if (!req) | 648 | if (!req) |
563 | return ERR_PTR(-ENOMEM); | 649 | return ERR_PTR(-ENOMEM); |
564 | osd_data = opcode == CEPH_OSD_OP_WRITE ? &req->r_data_out | ||
565 | : &req->r_data_in; | ||
566 | 650 | ||
567 | req->r_flags = flags; | 651 | req->r_flags = flags; |
568 | 652 | ||
@@ -585,7 +669,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
585 | 669 | ||
586 | osd_req_op_extent_init(req, 0, opcode, objoff, objlen, | 670 | osd_req_op_extent_init(req, 0, opcode, objoff, objlen, |
587 | truncate_size, truncate_seq); | 671 | truncate_size, truncate_seq); |
588 | osd_req_op_extent_osd_data(req, 0, osd_data); | ||
589 | 672 | ||
590 | /* | 673 | /* |
591 | * A second op in the ops array means the caller wants to | 674 | * A second op in the ops array means the caller wants to |
@@ -2171,8 +2254,8 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, | |||
2171 | 2254 | ||
2172 | /* it may be a short read due to an object boundary */ | 2255 | /* it may be a short read due to an object boundary */ |
2173 | 2256 | ||
2174 | ceph_osd_data_pages_init(&req->r_data_in, pages, *plen, page_align, | 2257 | osd_req_op_extent_osd_data_pages(req, 0, false, |
2175 | false, false); | 2258 | pages, *plen, page_align, false, false); |
2176 | 2259 | ||
2177 | dout("readpages final extent is %llu~%llu (%llu bytes align %d)\n", | 2260 | dout("readpages final extent is %llu~%llu (%llu bytes align %d)\n", |
2178 | off, *plen, *plen, page_align); | 2261 | off, *plen, *plen, page_align); |
@@ -2214,7 +2297,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, | |||
2214 | return PTR_ERR(req); | 2297 | return PTR_ERR(req); |
2215 | 2298 | ||
2216 | /* it may be a short write due to an object boundary */ | 2299 | /* it may be a short write due to an object boundary */ |
2217 | ceph_osd_data_pages_init(&req->r_data_out, pages, len, page_align, | 2300 | osd_req_op_extent_osd_data_pages(req, 0, true, pages, len, page_align, |
2218 | false, false); | 2301 | false, false); |
2219 | dout("writepages %llu~%llu (%llu bytes)\n", off, len, len); | 2302 | dout("writepages %llu~%llu (%llu bytes)\n", off, len, len); |
2220 | 2303 | ||
@@ -2308,8 +2391,14 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
2308 | m = ceph_msg_get(req->r_reply); | 2391 | m = ceph_msg_get(req->r_reply); |
2309 | 2392 | ||
2310 | if (data_len > 0) { | 2393 | if (data_len > 0) { |
2311 | struct ceph_osd_data *osd_data = &req->r_data_in; | 2394 | struct ceph_osd_data *osd_data; |
2312 | 2395 | ||
2396 | /* | ||
2397 | * XXX This is assuming there is only one op containing | ||
2398 | * XXX page data. Probably OK for reads, but this | ||
2399 | * XXX ought to be done more generally. | ||
2400 | */ | ||
2401 | osd_data = osd_req_op_extent_osd_data(req, 0, false); | ||
2313 | if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) { | 2402 | if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) { |
2314 | if (osd_data->pages && | 2403 | if (osd_data->pages && |
2315 | unlikely(osd_data->length < data_len)) { | 2404 | unlikely(osd_data->length < data_len)) { |