diff options
-rw-r--r-- | drivers/block/rbd.c | 117 | ||||
-rw-r--r-- | include/linux/ceph/osd_client.h | 26 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 84 |
3 files changed, 111 insertions, 116 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 6ed508bd363a..f04d45b6b563 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -1134,76 +1134,6 @@ static bool obj_request_type_valid(enum obj_request_type type) | |||
1134 | } | 1134 | } |
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | static struct ceph_osd_req_op *rbd_osd_req_op_create(u16 opcode, ...) | ||
1138 | { | ||
1139 | struct ceph_osd_req_op *op; | ||
1140 | va_list args; | ||
1141 | size_t size; | ||
1142 | |||
1143 | op = kzalloc(sizeof (*op), GFP_NOIO); | ||
1144 | if (!op) | ||
1145 | return NULL; | ||
1146 | op->op = opcode; | ||
1147 | va_start(args, opcode); | ||
1148 | switch (opcode) { | ||
1149 | case CEPH_OSD_OP_READ: | ||
1150 | case CEPH_OSD_OP_WRITE: | ||
1151 | /* rbd_osd_req_op_create(READ, offset, length) */ | ||
1152 | /* rbd_osd_req_op_create(WRITE, offset, length) */ | ||
1153 | op->extent.offset = va_arg(args, u64); | ||
1154 | op->extent.length = va_arg(args, u64); | ||
1155 | if (opcode == CEPH_OSD_OP_WRITE) | ||
1156 | op->payload_len = op->extent.length; | ||
1157 | break; | ||
1158 | case CEPH_OSD_OP_STAT: | ||
1159 | break; | ||
1160 | case CEPH_OSD_OP_CALL: | ||
1161 | /* rbd_osd_req_op_create(CALL, class, method, data, datalen) */ | ||
1162 | op->cls.class_name = va_arg(args, char *); | ||
1163 | size = strlen(op->cls.class_name); | ||
1164 | rbd_assert(size <= (size_t) U8_MAX); | ||
1165 | op->cls.class_len = size; | ||
1166 | op->payload_len = size; | ||
1167 | |||
1168 | op->cls.method_name = va_arg(args, char *); | ||
1169 | size = strlen(op->cls.method_name); | ||
1170 | rbd_assert(size <= (size_t) U8_MAX); | ||
1171 | op->cls.method_len = size; | ||
1172 | op->payload_len += size; | ||
1173 | |||
1174 | op->cls.argc = 0; | ||
1175 | op->cls.indata = va_arg(args, void *); | ||
1176 | size = va_arg(args, size_t); | ||
1177 | rbd_assert(size <= (size_t) U32_MAX); | ||
1178 | op->cls.indata_len = (u32) size; | ||
1179 | op->payload_len += size; | ||
1180 | break; | ||
1181 | case CEPH_OSD_OP_NOTIFY_ACK: | ||
1182 | case CEPH_OSD_OP_WATCH: | ||
1183 | /* rbd_osd_req_op_create(NOTIFY_ACK, cookie, version) */ | ||
1184 | /* rbd_osd_req_op_create(WATCH, cookie, version, flag) */ | ||
1185 | op->watch.cookie = va_arg(args, u64); | ||
1186 | op->watch.ver = va_arg(args, u64); | ||
1187 | op->watch.ver = cpu_to_le64(op->watch.ver); | ||
1188 | if (opcode == CEPH_OSD_OP_WATCH && va_arg(args, int)) | ||
1189 | op->watch.flag = (u8) 1; | ||
1190 | break; | ||
1191 | default: | ||
1192 | rbd_warn(NULL, "unsupported opcode %hu\n", opcode); | ||
1193 | kfree(op); | ||
1194 | op = NULL; | ||
1195 | break; | ||
1196 | } | ||
1197 | va_end(args); | ||
1198 | |||
1199 | return op; | ||
1200 | } | ||
1201 | |||
1202 | static void rbd_osd_req_op_destroy(struct ceph_osd_req_op *op) | ||
1203 | { | ||
1204 | kfree(op); | ||
1205 | } | ||
1206 | |||
1207 | static int rbd_obj_request_submit(struct ceph_osd_client *osdc, | 1137 | static int rbd_obj_request_submit(struct ceph_osd_client *osdc, |
1208 | struct rbd_obj_request *obj_request) | 1138 | struct rbd_obj_request *obj_request) |
1209 | { | 1139 | { |
@@ -1628,7 +1558,7 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, | |||
1628 | while (resid) { | 1558 | while (resid) { |
1629 | const char *object_name; | 1559 | const char *object_name; |
1630 | unsigned int clone_size; | 1560 | unsigned int clone_size; |
1631 | struct ceph_osd_req_op *op; | 1561 | struct ceph_osd_req_op op; |
1632 | u64 offset; | 1562 | u64 offset; |
1633 | u64 length; | 1563 | u64 length; |
1634 | 1564 | ||
@@ -1657,13 +1587,10 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request, | |||
1657 | * request. Note that the contents of the op are | 1587 | * request. Note that the contents of the op are |
1658 | * copied by rbd_osd_req_create(). | 1588 | * copied by rbd_osd_req_create(). |
1659 | */ | 1589 | */ |
1660 | op = rbd_osd_req_op_create(opcode, offset, length); | 1590 | osd_req_op_extent_init(&op, opcode, offset, length, 0, 0); |
1661 | if (!op) | ||
1662 | goto out_partial; | ||
1663 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, | 1591 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, |
1664 | img_request->write_request, | 1592 | img_request->write_request, |
1665 | obj_request, op); | 1593 | obj_request, &op); |
1666 | rbd_osd_req_op_destroy(op); | ||
1667 | if (!obj_request->osd_req) | 1594 | if (!obj_request->osd_req) |
1668 | goto out_partial; | 1595 | goto out_partial; |
1669 | /* status and version are initially zero-filled */ | 1596 | /* status and version are initially zero-filled */ |
@@ -1766,7 +1693,7 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev, | |||
1766 | u64 ver, u64 notify_id) | 1693 | u64 ver, u64 notify_id) |
1767 | { | 1694 | { |
1768 | struct rbd_obj_request *obj_request; | 1695 | struct rbd_obj_request *obj_request; |
1769 | struct ceph_osd_req_op *op; | 1696 | struct ceph_osd_req_op op; |
1770 | struct ceph_osd_client *osdc; | 1697 | struct ceph_osd_client *osdc; |
1771 | int ret; | 1698 | int ret; |
1772 | 1699 | ||
@@ -1776,12 +1703,9 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev, | |||
1776 | return -ENOMEM; | 1703 | return -ENOMEM; |
1777 | 1704 | ||
1778 | ret = -ENOMEM; | 1705 | ret = -ENOMEM; |
1779 | op = rbd_osd_req_op_create(CEPH_OSD_OP_NOTIFY_ACK, notify_id, ver); | 1706 | osd_req_op_watch_init(&op, CEPH_OSD_OP_NOTIFY_ACK, notify_id, ver, 0); |
1780 | if (!op) | ||
1781 | goto out; | ||
1782 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, | 1707 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, |
1783 | obj_request, op); | 1708 | obj_request, &op); |
1784 | rbd_osd_req_op_destroy(op); | ||
1785 | if (!obj_request->osd_req) | 1709 | if (!obj_request->osd_req) |
1786 | goto out; | 1710 | goto out; |
1787 | 1711 | ||
@@ -1823,7 +1747,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) | |||
1823 | { | 1747 | { |
1824 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; | 1748 | struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; |
1825 | struct rbd_obj_request *obj_request; | 1749 | struct rbd_obj_request *obj_request; |
1826 | struct ceph_osd_req_op *op; | 1750 | struct ceph_osd_req_op op; |
1827 | int ret; | 1751 | int ret; |
1828 | 1752 | ||
1829 | rbd_assert(start ^ !!rbd_dev->watch_event); | 1753 | rbd_assert(start ^ !!rbd_dev->watch_event); |
@@ -1843,14 +1767,11 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start) | |||
1843 | if (!obj_request) | 1767 | if (!obj_request) |
1844 | goto out_cancel; | 1768 | goto out_cancel; |
1845 | 1769 | ||
1846 | op = rbd_osd_req_op_create(CEPH_OSD_OP_WATCH, | 1770 | osd_req_op_watch_init(&op, CEPH_OSD_OP_WATCH, |
1847 | rbd_dev->watch_event->cookie, | 1771 | rbd_dev->watch_event->cookie, |
1848 | rbd_dev->header.obj_version, start); | 1772 | rbd_dev->header.obj_version, start); |
1849 | if (!op) | ||
1850 | goto out_cancel; | ||
1851 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, | 1773 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, true, |
1852 | obj_request, op); | 1774 | obj_request, &op); |
1853 | rbd_osd_req_op_destroy(op); | ||
1854 | if (!obj_request->osd_req) | 1775 | if (!obj_request->osd_req) |
1855 | goto out_cancel; | 1776 | goto out_cancel; |
1856 | 1777 | ||
@@ -1912,7 +1833,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, | |||
1912 | { | 1833 | { |
1913 | struct rbd_obj_request *obj_request; | 1834 | struct rbd_obj_request *obj_request; |
1914 | struct ceph_osd_client *osdc; | 1835 | struct ceph_osd_client *osdc; |
1915 | struct ceph_osd_req_op *op; | 1836 | struct ceph_osd_req_op op; |
1916 | struct page **pages; | 1837 | struct page **pages; |
1917 | u32 page_count; | 1838 | u32 page_count; |
1918 | int ret; | 1839 | int ret; |
@@ -1939,13 +1860,10 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, | |||
1939 | obj_request->pages = pages; | 1860 | obj_request->pages = pages; |
1940 | obj_request->page_count = page_count; | 1861 | obj_request->page_count = page_count; |
1941 | 1862 | ||
1942 | op = rbd_osd_req_op_create(CEPH_OSD_OP_CALL, class_name, | 1863 | osd_req_op_cls_init(&op, CEPH_OSD_OP_CALL, class_name, method_name, |
1943 | method_name, outbound, outbound_size); | 1864 | outbound, outbound_size); |
1944 | if (!op) | ||
1945 | goto out; | ||
1946 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, | 1865 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, |
1947 | obj_request, op); | 1866 | obj_request, &op); |
1948 | rbd_osd_req_op_destroy(op); | ||
1949 | if (!obj_request->osd_req) | 1867 | if (!obj_request->osd_req) |
1950 | goto out; | 1868 | goto out; |
1951 | 1869 | ||
@@ -2125,7 +2043,7 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, | |||
2125 | char *buf, u64 *version) | 2043 | char *buf, u64 *version) |
2126 | 2044 | ||
2127 | { | 2045 | { |
2128 | struct ceph_osd_req_op *op; | 2046 | struct ceph_osd_req_op op; |
2129 | struct rbd_obj_request *obj_request; | 2047 | struct rbd_obj_request *obj_request; |
2130 | struct ceph_osd_client *osdc; | 2048 | struct ceph_osd_client *osdc; |
2131 | struct page **pages = NULL; | 2049 | struct page **pages = NULL; |
@@ -2147,12 +2065,9 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev, | |||
2147 | obj_request->pages = pages; | 2065 | obj_request->pages = pages; |
2148 | obj_request->page_count = page_count; | 2066 | obj_request->page_count = page_count; |
2149 | 2067 | ||
2150 | op = rbd_osd_req_op_create(CEPH_OSD_OP_READ, offset, length); | 2068 | osd_req_op_extent_init(&op, CEPH_OSD_OP_READ, offset, length, 0, 0); |
2151 | if (!op) | ||
2152 | goto out; | ||
2153 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, | 2069 | obj_request->osd_req = rbd_osd_req_create(rbd_dev, false, |
2154 | obj_request, op); | 2070 | obj_request, &op); |
2155 | rbd_osd_req_op_destroy(op); | ||
2156 | if (!obj_request->osd_req) | 2071 | if (!obj_request->osd_req) |
2157 | goto out; | 2072 | goto out; |
2158 | 2073 | ||
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 1dab291b2dc6..5fd2cbfcfd91 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h | |||
@@ -202,14 +202,6 @@ struct ceph_osd_req_op { | |||
202 | u32 truncate_seq; | 202 | u32 truncate_seq; |
203 | } extent; | 203 | } extent; |
204 | struct { | 204 | struct { |
205 | const char *name; | ||
206 | const void *val; | ||
207 | u32 name_len; | ||
208 | u32 value_len; | ||
209 | __u8 cmp_op; /* CEPH_OSD_CMPXATTR_OP_* */ | ||
210 | __u8 cmp_mode; /* CEPH_OSD_CMPXATTR_MODE_* */ | ||
211 | } xattr; | ||
212 | struct { | ||
213 | const char *class_name; | 205 | const char *class_name; |
214 | const char *method_name; | 206 | const char *method_name; |
215 | const void *indata; | 207 | const void *indata; |
@@ -220,13 +212,6 @@ struct ceph_osd_req_op { | |||
220 | } cls; | 212 | } cls; |
221 | struct { | 213 | struct { |
222 | u64 cookie; | 214 | u64 cookie; |
223 | u64 count; | ||
224 | } pgls; | ||
225 | struct { | ||
226 | u64 snapid; | ||
227 | } snap; | ||
228 | struct { | ||
229 | u64 cookie; | ||
230 | u64 ver; | 215 | u64 ver; |
231 | u32 prot_ver; | 216 | u32 prot_ver; |
232 | u32 timeout; | 217 | u32 timeout; |
@@ -244,6 +229,17 @@ extern void ceph_osdc_handle_reply(struct ceph_osd_client *osdc, | |||
244 | extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, | 229 | extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc, |
245 | struct ceph_msg *msg); | 230 | struct ceph_msg *msg); |
246 | 231 | ||
232 | extern void osd_req_op_init(struct ceph_osd_req_op *op, u16 opcode); | ||
233 | extern void osd_req_op_extent_init(struct ceph_osd_req_op *op, u16 opcode, | ||
234 | u64 offset, u64 length, | ||
235 | u64 truncate_size, u32 truncate_seq); | ||
236 | extern void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, | ||
237 | const char *class, const char *method, | ||
238 | const void *request_data, | ||
239 | size_t request_data_size); | ||
240 | extern void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, | ||
241 | u64 cookie, u64 version, int flag); | ||
242 | |||
247 | extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, | 243 | extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, |
248 | struct ceph_snap_context *snapc, | 244 | struct ceph_snap_context *snapc, |
249 | unsigned int num_op, | 245 | unsigned int num_op, |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 4e5c0438ea35..02ed72820479 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -289,6 +289,90 @@ static bool osd_req_opcode_valid(u16 opcode) | |||
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | /* | ||
293 | * This is an osd op init function for opcodes that have no data or | ||
294 | * other information associated with them. It also serves as a | ||
295 | * common init routine for all the other init functions, below. | ||
296 | */ | ||
297 | void osd_req_op_init(struct ceph_osd_req_op *op, u16 opcode) | ||
298 | { | ||
299 | BUG_ON(!osd_req_opcode_valid(opcode)); | ||
300 | |||
301 | memset(op, 0, sizeof (*op)); | ||
302 | |||
303 | op->op = opcode; | ||
304 | } | ||
305 | |||
306 | void osd_req_op_extent_init(struct ceph_osd_req_op *op, u16 opcode, | ||
307 | u64 offset, u64 length, | ||
308 | u64 truncate_size, u32 truncate_seq) | ||
309 | { | ||
310 | size_t payload_len = 0; | ||
311 | |||
312 | BUG_ON(opcode != CEPH_OSD_OP_READ && opcode != CEPH_OSD_OP_WRITE); | ||
313 | |||
314 | osd_req_op_init(op, opcode); | ||
315 | |||
316 | op->extent.offset = offset; | ||
317 | op->extent.length = length; | ||
318 | op->extent.truncate_size = truncate_size; | ||
319 | op->extent.truncate_seq = truncate_seq; | ||
320 | if (opcode == CEPH_OSD_OP_WRITE) | ||
321 | payload_len += length; | ||
322 | |||
323 | op->payload_len = payload_len; | ||
324 | } | ||
325 | EXPORT_SYMBOL(osd_req_op_extent_init); | ||
326 | |||
327 | void osd_req_op_cls_init(struct ceph_osd_req_op *op, u16 opcode, | ||
328 | const char *class, const char *method, | ||
329 | const void *request_data, size_t request_data_size) | ||
330 | { | ||
331 | size_t payload_len = 0; | ||
332 | size_t size; | ||
333 | |||
334 | BUG_ON(opcode != CEPH_OSD_OP_CALL); | ||
335 | |||
336 | osd_req_op_init(op, opcode); | ||
337 | |||
338 | op->cls.class_name = class; | ||
339 | size = strlen(class); | ||
340 | BUG_ON(size > (size_t) U8_MAX); | ||
341 | op->cls.class_len = size; | ||
342 | payload_len += size; | ||
343 | |||
344 | op->cls.method_name = method; | ||
345 | size = strlen(method); | ||
346 | BUG_ON(size > (size_t) U8_MAX); | ||
347 | op->cls.method_len = size; | ||
348 | payload_len += size; | ||
349 | |||
350 | op->cls.indata = request_data; | ||
351 | BUG_ON(request_data_size > (size_t) U32_MAX); | ||
352 | op->cls.indata_len = (u32) request_data_size; | ||
353 | payload_len += request_data_size; | ||
354 | |||
355 | op->cls.argc = 0; /* currently unused */ | ||
356 | |||
357 | op->payload_len = payload_len; | ||
358 | } | ||
359 | EXPORT_SYMBOL(osd_req_op_cls_init); | ||
360 | |||
361 | void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode, | ||
362 | u64 cookie, u64 version, int flag) | ||
363 | { | ||
364 | BUG_ON(opcode != CEPH_OSD_OP_NOTIFY_ACK && opcode != CEPH_OSD_OP_WATCH); | ||
365 | |||
366 | osd_req_op_init(op, opcode); | ||
367 | |||
368 | op->watch.cookie = cookie; | ||
369 | /* op->watch.ver = version; */ /* XXX 3847 */ | ||
370 | op->watch.ver = cpu_to_le64(version); | ||
371 | if (opcode == CEPH_OSD_OP_WATCH && flag) | ||
372 | op->watch.flag = (u8) 1; | ||
373 | } | ||
374 | EXPORT_SYMBOL(osd_req_op_watch_init); | ||
375 | |||
292 | static u64 osd_req_encode_op(struct ceph_osd_request *req, | 376 | static u64 osd_req_encode_op(struct ceph_osd_request *req, |
293 | struct ceph_osd_op *dst, | 377 | struct ceph_osd_op *dst, |
294 | struct ceph_osd_req_op *src) | 378 | struct ceph_osd_req_op *src) |