aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c42
-rw-r--r--fs/ceph/addr.c21
-rw-r--r--fs/ceph/file.c6
-rw-r--r--include/linux/ceph/osd_client.h70
-rw-r--r--net/ceph/debugfs.c4
-rw-r--r--net/ceph/osd_client.c53
6 files changed, 97 insertions, 99 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 4a4be14a9189..c12b55559f16 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1285,7 +1285,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
1285 */ 1285 */
1286 obj_request->xferred = osd_req->r_reply_op_len[0]; 1286 obj_request->xferred = osd_req->r_reply_op_len[0];
1287 rbd_assert(obj_request->xferred < (u64) UINT_MAX); 1287 rbd_assert(obj_request->xferred < (u64) UINT_MAX);
1288 opcode = osd_req->r_request_ops[0].op; 1288 opcode = osd_req->r_ops[0].op;
1289 switch (opcode) { 1289 switch (opcode) {
1290 case CEPH_OSD_OP_READ: 1290 case CEPH_OSD_OP_READ:
1291 rbd_osd_read_callback(obj_request); 1291 rbd_osd_read_callback(obj_request);
@@ -1312,8 +1312,7 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req,
1312} 1312}
1313 1313
1314static void rbd_osd_req_format_op(struct rbd_obj_request *obj_request, 1314static void rbd_osd_req_format_op(struct rbd_obj_request *obj_request,
1315 bool write_request, 1315 bool write_request)
1316 struct ceph_osd_req_op *op)
1317{ 1316{
1318 struct rbd_img_request *img_request = obj_request->img_request; 1317 struct rbd_img_request *img_request = obj_request->img_request;
1319 struct ceph_snap_context *snapc = NULL; 1318 struct ceph_snap_context *snapc = NULL;
@@ -1333,7 +1332,7 @@ static void rbd_osd_req_format_op(struct rbd_obj_request *obj_request,
1333 } 1332 }
1334 1333
1335 ceph_osdc_build_request(obj_request->osd_req, obj_request->offset, 1334 ceph_osdc_build_request(obj_request->osd_req, obj_request->offset,
1336 1, op, snapc, snap_id, mtime); 1335 snapc, snap_id, mtime);
1337} 1336}
1338 1337
1339static struct ceph_osd_request *rbd_osd_req_create( 1338static struct ceph_osd_request *rbd_osd_req_create(
@@ -1562,7 +1561,7 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1562 while (resid) { 1561 while (resid) {
1563 const char *object_name; 1562 const char *object_name;
1564 unsigned int clone_size; 1563 unsigned int clone_size;
1565 struct ceph_osd_req_op op; 1564 struct ceph_osd_req_op *op;
1566 u64 offset; 1565 u64 offset;
1567 u64 length; 1566 u64 length;
1568 1567
@@ -1591,8 +1590,9 @@ static int rbd_img_request_fill_bio(struct rbd_img_request *img_request,
1591 if (!obj_request->osd_req) 1590 if (!obj_request->osd_req)
1592 goto out_partial; 1591 goto out_partial;
1593 1592
1594 osd_req_op_extent_init(&op, opcode, offset, length, 0, 0); 1593 op = &obj_request->osd_req->r_ops[0];
1595 rbd_osd_req_format_op(obj_request, write_request, &op); 1594 osd_req_op_extent_init(op, opcode, offset, length, 0, 0);
1595 rbd_osd_req_format_op(obj_request, write_request);
1596 1596
1597 /* status and version are initially zero-filled */ 1597 /* status and version are initially zero-filled */
1598 1598
@@ -1694,7 +1694,7 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev,
1694 u64 ver, u64 notify_id) 1694 u64 ver, u64 notify_id)
1695{ 1695{
1696 struct rbd_obj_request *obj_request; 1696 struct rbd_obj_request *obj_request;
1697 struct ceph_osd_req_op op; 1697 struct ceph_osd_req_op *op;
1698 struct ceph_osd_client *osdc; 1698 struct ceph_osd_client *osdc;
1699 int ret; 1699 int ret;
1700 1700
@@ -1708,8 +1708,9 @@ static int rbd_obj_notify_ack(struct rbd_device *rbd_dev,
1708 if (!obj_request->osd_req) 1708 if (!obj_request->osd_req)
1709 goto out; 1709 goto out;
1710 1710
1711 osd_req_op_watch_init(&op, CEPH_OSD_OP_NOTIFY_ACK, notify_id, ver, 0); 1711 op = &obj_request->osd_req->r_ops[0];
1712 rbd_osd_req_format_op(obj_request, false, &op); 1712 osd_req_op_watch_init(op, CEPH_OSD_OP_NOTIFY_ACK, notify_id, ver, 0);
1713 rbd_osd_req_format_op(obj_request, false);
1713 1714
1714 osdc = &rbd_dev->rbd_client->client->osdc; 1715 osdc = &rbd_dev->rbd_client->client->osdc;
1715 obj_request->callback = rbd_obj_request_put; 1716 obj_request->callback = rbd_obj_request_put;
@@ -1749,7 +1750,7 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
1749{ 1750{
1750 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; 1751 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
1751 struct rbd_obj_request *obj_request; 1752 struct rbd_obj_request *obj_request;
1752 struct ceph_osd_req_op op; 1753 struct ceph_osd_req_op *op;
1753 int ret; 1754 int ret;
1754 1755
1755 rbd_assert(start ^ !!rbd_dev->watch_event); 1756 rbd_assert(start ^ !!rbd_dev->watch_event);
@@ -1773,10 +1774,11 @@ static int rbd_dev_header_watch_sync(struct rbd_device *rbd_dev, int start)
1773 if (!obj_request->osd_req) 1774 if (!obj_request->osd_req)
1774 goto out_cancel; 1775 goto out_cancel;
1775 1776
1776 osd_req_op_watch_init(&op, CEPH_OSD_OP_WATCH, 1777 op = &obj_request->osd_req->r_ops[0];
1778 osd_req_op_watch_init(op, CEPH_OSD_OP_WATCH,
1777 rbd_dev->watch_event->cookie, 1779 rbd_dev->watch_event->cookie,
1778 rbd_dev->header.obj_version, start); 1780 rbd_dev->header.obj_version, start);
1779 rbd_osd_req_format_op(obj_request, true, &op); 1781 rbd_osd_req_format_op(obj_request, true);
1780 1782
1781 if (start) 1783 if (start)
1782 ceph_osdc_set_request_linger(osdc, obj_request->osd_req); 1784 ceph_osdc_set_request_linger(osdc, obj_request->osd_req);
@@ -1836,7 +1838,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
1836{ 1838{
1837 struct rbd_obj_request *obj_request; 1839 struct rbd_obj_request *obj_request;
1838 struct ceph_osd_client *osdc; 1840 struct ceph_osd_client *osdc;
1839 struct ceph_osd_req_op op; 1841 struct ceph_osd_req_op *op;
1840 struct page **pages; 1842 struct page **pages;
1841 u32 page_count; 1843 u32 page_count;
1842 int ret; 1844 int ret;
@@ -1866,9 +1868,10 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
1866 if (!obj_request->osd_req) 1868 if (!obj_request->osd_req)
1867 goto out; 1869 goto out;
1868 1870
1869 osd_req_op_cls_init(&op, CEPH_OSD_OP_CALL, class_name, method_name, 1871 op = &obj_request->osd_req->r_ops[0];
1872 osd_req_op_cls_init(op, CEPH_OSD_OP_CALL, class_name, method_name,
1870 outbound, outbound_size); 1873 outbound, outbound_size);
1871 rbd_osd_req_format_op(obj_request, false, &op); 1874 rbd_osd_req_format_op(obj_request, false);
1872 1875
1873 osdc = &rbd_dev->rbd_client->client->osdc; 1876 osdc = &rbd_dev->rbd_client->client->osdc;
1874 ret = rbd_obj_request_submit(osdc, obj_request); 1877 ret = rbd_obj_request_submit(osdc, obj_request);
@@ -2046,8 +2049,8 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
2046 char *buf, u64 *version) 2049 char *buf, u64 *version)
2047 2050
2048{ 2051{
2049 struct ceph_osd_req_op op;
2050 struct rbd_obj_request *obj_request; 2052 struct rbd_obj_request *obj_request;
2053 struct ceph_osd_req_op *op;
2051 struct ceph_osd_client *osdc; 2054 struct ceph_osd_client *osdc;
2052 struct page **pages = NULL; 2055 struct page **pages = NULL;
2053 u32 page_count; 2056 u32 page_count;
@@ -2072,8 +2075,9 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,
2072 if (!obj_request->osd_req) 2075 if (!obj_request->osd_req)
2073 goto out; 2076 goto out;
2074 2077
2075 osd_req_op_extent_init(&op, CEPH_OSD_OP_READ, offset, length, 0, 0); 2078 op = &obj_request->osd_req->r_ops[0];
2076 rbd_osd_req_format_op(obj_request, false, &op); 2079 osd_req_op_extent_init(op, CEPH_OSD_OP_READ, offset, length, 0, 0);
2080 rbd_osd_req_format_op(obj_request, false);
2077 2081
2078 osdc = &rbd_dev->rbd_client->client->osdc; 2082 osdc = &rbd_dev->rbd_client->client->osdc;
2079 ret = rbd_obj_request_submit(osdc, obj_request); 2083 ret = rbd_obj_request_submit(osdc, obj_request);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 127be29a6c22..c9da074f0fe6 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -288,7 +288,6 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
288 struct page *page = list_entry(page_list->prev, struct page, lru); 288 struct page *page = list_entry(page_list->prev, struct page, lru);
289 struct ceph_vino vino; 289 struct ceph_vino vino;
290 struct ceph_osd_request *req; 290 struct ceph_osd_request *req;
291 struct ceph_osd_req_op op;
292 u64 off; 291 u64 off;
293 u64 len; 292 u64 len;
294 int i; 293 int i;
@@ -314,7 +313,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
314 off, len); 313 off, len);
315 vino = ceph_vino(inode); 314 vino = ceph_vino(inode);
316 req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len, 315 req = ceph_osdc_new_request(osdc, &ci->i_layout, vino, off, &len,
317 1, &op, CEPH_OSD_OP_READ, 316 1, CEPH_OSD_OP_READ,
318 CEPH_OSD_FLAG_READ, NULL, 317 CEPH_OSD_FLAG_READ, NULL,
319 ci->i_truncate_seq, ci->i_truncate_size, 318 ci->i_truncate_seq, ci->i_truncate_size,
320 false); 319 false);
@@ -349,7 +348,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
349 req->r_callback = finish_read; 348 req->r_callback = finish_read;
350 req->r_inode = inode; 349 req->r_inode = inode;
351 350
352 ceph_osdc_build_request(req, off, 1, &op, NULL, vino.snap, NULL); 351 ceph_osdc_build_request(req, off, NULL, vino.snap, NULL);
353 352
354 dout("start_read %p starting %p %lld~%lld\n", inode, req, off, len); 353 dout("start_read %p starting %p %lld~%lld\n", inode, req, off, len);
355 ret = ceph_osdc_start_request(osdc, req, false); 354 ret = ceph_osdc_start_request(osdc, req, false);
@@ -567,7 +566,7 @@ static void writepages_finish(struct ceph_osd_request *req,
567 struct ceph_snap_context *snapc = req->r_snapc; 566 struct ceph_snap_context *snapc = req->r_snapc;
568 struct address_space *mapping = inode->i_mapping; 567 struct address_space *mapping = inode->i_mapping;
569 int rc = req->r_result; 568 int rc = req->r_result;
570 u64 bytes = le64_to_cpu(req->r_request_ops[0].extent.length); 569 u64 bytes = req->r_ops[0].extent.length;
571 struct ceph_fs_client *fsc = ceph_inode_to_client(inode); 570 struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
572 long writeback_stat; 571 long writeback_stat;
573 unsigned issued = ceph_caps_issued(ci); 572 unsigned issued = ceph_caps_issued(ci);
@@ -635,8 +634,7 @@ static void writepages_finish(struct ceph_osd_request *req,
635 634
636static struct ceph_osd_request * 635static struct ceph_osd_request *
637ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len, 636ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len,
638 struct ceph_snap_context *snapc, 637 struct ceph_snap_context *snapc, int num_ops)
639 int num_ops, struct ceph_osd_req_op *ops)
640{ 638{
641 struct ceph_fs_client *fsc; 639 struct ceph_fs_client *fsc;
642 struct ceph_inode_info *ci; 640 struct ceph_inode_info *ci;
@@ -648,7 +646,7 @@ ceph_writepages_osd_request(struct inode *inode, u64 offset, u64 *len,
648 /* BUG_ON(vino.snap != CEPH_NOSNAP); */ 646 /* BUG_ON(vino.snap != CEPH_NOSNAP); */
649 647
650 return ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, 648 return ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
651 vino, offset, len, num_ops, ops, CEPH_OSD_OP_WRITE, 649 vino, offset, len, num_ops, CEPH_OSD_OP_WRITE,
652 CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK, 650 CEPH_OSD_FLAG_WRITE|CEPH_OSD_FLAG_ONDISK,
653 snapc, ci->i_truncate_seq, ci->i_truncate_size, true); 651 snapc, ci->i_truncate_seq, ci->i_truncate_size, true);
654} 652}
@@ -738,7 +736,6 @@ retry:
738 last_snapc = snapc; 736 last_snapc = snapc;
739 737
740 while (!done && index <= end) { 738 while (!done && index <= end) {
741 struct ceph_osd_req_op ops[2];
742 int num_ops = do_sync ? 2 : 1; 739 int num_ops = do_sync ? 2 : 1;
743 struct ceph_vino vino; 740 struct ceph_vino vino;
744 unsigned i; 741 unsigned i;
@@ -846,7 +843,7 @@ get_more_pages:
846 len = wsize; 843 len = wsize;
847 req = ceph_writepages_osd_request(inode, 844 req = ceph_writepages_osd_request(inode,
848 offset, &len, snapc, 845 offset, &len, snapc,
849 num_ops, ops); 846 num_ops);
850 847
851 if (IS_ERR(req)) { 848 if (IS_ERR(req)) {
852 rc = PTR_ERR(req); 849 rc = PTR_ERR(req);
@@ -927,11 +924,11 @@ get_more_pages:
927 924
928 /* Update the write op length in case we changed it */ 925 /* Update the write op length in case we changed it */
929 926
930 osd_req_op_extent_update(&ops[0], len); 927 osd_req_op_extent_update(&req->r_ops[0], len);
931 928
932 vino = ceph_vino(inode); 929 vino = ceph_vino(inode);
933 ceph_osdc_build_request(req, offset, num_ops, ops, 930 ceph_osdc_build_request(req, offset, snapc, vino.snap,
934 snapc, vino.snap, &inode->i_mtime); 931 &inode->i_mtime);
935 932
936 rc = ceph_osdc_start_request(&fsc->client->osdc, req, true); 933 rc = ceph_osdc_start_request(&fsc->client->osdc, req, true);
937 BUG_ON(rc); 934 BUG_ON(rc);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index da642af14a28..a12f47642c40 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -478,7 +478,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
478 struct ceph_snap_context *snapc; 478 struct ceph_snap_context *snapc;
479 struct ceph_vino vino; 479 struct ceph_vino vino;
480 struct ceph_osd_request *req; 480 struct ceph_osd_request *req;
481 struct ceph_osd_req_op ops[2];
482 int num_ops = 1; 481 int num_ops = 1;
483 struct page **pages; 482 struct page **pages;
484 int num_pages; 483 int num_pages;
@@ -534,7 +533,7 @@ more:
534 snapc = ci->i_snap_realm->cached_context; 533 snapc = ci->i_snap_realm->cached_context;
535 vino = ceph_vino(inode); 534 vino = ceph_vino(inode);
536 req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, 535 req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
537 vino, pos, &len, num_ops, ops, 536 vino, pos, &len, num_ops,
538 CEPH_OSD_OP_WRITE, flags, snapc, 537 CEPH_OSD_OP_WRITE, flags, snapc,
539 ci->i_truncate_seq, ci->i_truncate_size, 538 ci->i_truncate_seq, ci->i_truncate_size,
540 false); 539 false);
@@ -579,8 +578,7 @@ more:
579 false, own_pages); 578 false, own_pages);
580 579
581 /* BUG_ON(vino.snap != CEPH_NOSNAP); */ 580 /* BUG_ON(vino.snap != CEPH_NOSNAP); */
582 ceph_osdc_build_request(req, pos, num_ops, ops, 581 ceph_osdc_build_request(req, pos, snapc, vino.snap, &mtime);
583 snapc, vino.snap, &mtime);
584 582
585 ret = ceph_osdc_start_request(&fsc->client->osdc, req, false); 583 ret = ceph_osdc_start_request(&fsc->client->osdc, req, false);
586 if (!ret) { 584 if (!ret) {
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index af60dac1f9c0..f4c1a2a22a14 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -48,7 +48,7 @@ struct ceph_osd {
48}; 48};
49 49
50 50
51#define CEPH_OSD_MAX_OP 10 51#define CEPH_OSD_MAX_OP 2
52 52
53enum ceph_osd_data_type { 53enum ceph_osd_data_type {
54 CEPH_OSD_DATA_TYPE_NONE, 54 CEPH_OSD_DATA_TYPE_NONE,
@@ -79,6 +79,34 @@ struct ceph_osd_data {
79 }; 79 };
80}; 80};
81 81
82struct ceph_osd_req_op {
83 u16 op; /* CEPH_OSD_OP_* */
84 u32 payload_len;
85 union {
86 struct {
87 u64 offset, length;
88 u64 truncate_size;
89 u32 truncate_seq;
90 } extent;
91 struct {
92 const char *class_name;
93 const char *method_name;
94 const void *indata;
95 u32 indata_len;
96 __u8 class_len;
97 __u8 method_len;
98 __u8 argc;
99 } cls;
100 struct {
101 u64 cookie;
102 u64 ver;
103 u32 prot_ver;
104 u32 timeout;
105 __u8 flag;
106 } watch;
107 };
108};
109
82/* an in-flight request */ 110/* an in-flight request */
83struct ceph_osd_request { 111struct ceph_osd_request {
84 u64 r_tid; /* unique for this client */ 112 u64 r_tid; /* unique for this client */
@@ -95,10 +123,11 @@ struct ceph_osd_request {
95 struct ceph_msg *r_request, *r_reply; 123 struct ceph_msg *r_request, *r_reply;
96 int r_flags; /* any additional flags for the osd */ 124 int r_flags; /* any additional flags for the osd */
97 u32 r_sent; /* >0 if r_request is sending/sent */ 125 u32 r_sent; /* >0 if r_request is sending/sent */
98 int r_num_ops;
99 126
100 /* encoded message content */ 127 /* request osd ops array */
101 struct ceph_osd_op *r_request_ops; 128 unsigned int r_num_ops;
129 struct ceph_osd_req_op r_ops[CEPH_OSD_MAX_OP];
130
102 /* these are updated on each send */ 131 /* these are updated on each send */
103 __le32 *r_request_osdmap_epoch; 132 __le32 *r_request_osdmap_epoch;
104 __le32 *r_request_flags; 133 __le32 *r_request_flags;
@@ -193,34 +222,6 @@ struct ceph_osd_client {
193 struct workqueue_struct *notify_wq; 222 struct workqueue_struct *notify_wq;
194}; 223};
195 224
196struct ceph_osd_req_op {
197 u16 op; /* CEPH_OSD_OP_* */
198 u32 payload_len;
199 union {
200 struct {
201 u64 offset, length;
202 u64 truncate_size;
203 u32 truncate_seq;
204 } extent;
205 struct {
206 const char *class_name;
207 const char *method_name;
208 const void *indata;
209 u32 indata_len;
210 __u8 class_len;
211 __u8 method_len;
212 __u8 argc;
213 } cls;
214 struct {
215 u64 cookie;
216 u64 ver;
217 u32 prot_ver;
218 u32 timeout;
219 __u8 flag;
220 } watch;
221 };
222};
223
224extern int ceph_osdc_init(struct ceph_osd_client *osdc, 225extern int ceph_osdc_init(struct ceph_osd_client *osdc,
225 struct ceph_client *client); 226 struct ceph_client *client);
226extern void ceph_osdc_stop(struct ceph_osd_client *osdc); 227extern void ceph_osdc_stop(struct ceph_osd_client *osdc);
@@ -249,8 +250,6 @@ extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *
249 gfp_t gfp_flags); 250 gfp_t gfp_flags);
250 251
251extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, 252extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off,
252 unsigned int num_ops,
253 struct ceph_osd_req_op *src_ops,
254 struct ceph_snap_context *snapc, 253 struct ceph_snap_context *snapc,
255 u64 snap_id, 254 u64 snap_id,
256 struct timespec *mtime); 255 struct timespec *mtime);
@@ -259,8 +258,7 @@ extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *,
259 struct ceph_file_layout *layout, 258 struct ceph_file_layout *layout,
260 struct ceph_vino vino, 259 struct ceph_vino vino,
261 u64 offset, u64 *len, 260 u64 offset, u64 *len,
262 int num_ops, struct ceph_osd_req_op *ops, 261 int num_ops, int opcode, int flags,
263 int opcode, int flags,
264 struct ceph_snap_context *snapc, 262 struct ceph_snap_context *snapc,
265 u32 truncate_seq, u64 truncate_size, 263 u32 truncate_seq, u64 truncate_size,
266 bool use_mempool); 264 bool use_mempool);
diff --git a/net/ceph/debugfs.c b/net/ceph/debugfs.c
index 00d051f4894e..83661cdc0766 100644
--- a/net/ceph/debugfs.c
+++ b/net/ceph/debugfs.c
@@ -123,8 +123,8 @@ static int osdc_show(struct seq_file *s, void *pp)
123 mutex_lock(&osdc->request_mutex); 123 mutex_lock(&osdc->request_mutex);
124 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) { 124 for (p = rb_first(&osdc->requests); p; p = rb_next(p)) {
125 struct ceph_osd_request *req; 125 struct ceph_osd_request *req;
126 unsigned int i;
126 int opcode; 127 int opcode;
127 int i;
128 128
129 req = rb_entry(p, struct ceph_osd_request, r_node); 129 req = rb_entry(p, struct ceph_osd_request, r_node);
130 130
@@ -142,7 +142,7 @@ static int osdc_show(struct seq_file *s, void *pp)
142 seq_printf(s, "\t"); 142 seq_printf(s, "\t");
143 143
144 for (i = 0; i < req->r_num_ops; i++) { 144 for (i = 0; i < req->r_num_ops; i++) {
145 opcode = le16_to_cpu(req->r_request_ops[i].op); 145 opcode = req->r_ops[i].op;
146 seq_printf(s, "\t%s", ceph_osd_op_name(opcode)); 146 seq_printf(s, "\t%s", ceph_osd_op_name(opcode));
147 } 147 }
148 148
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index e197c5c0b3a2..a498d2de17a4 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -186,6 +186,9 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
186 struct ceph_msg *msg; 186 struct ceph_msg *msg;
187 size_t msg_size; 187 size_t msg_size;
188 188
189 BUILD_BUG_ON(CEPH_OSD_MAX_OP > U16_MAX);
190 BUG_ON(num_ops > CEPH_OSD_MAX_OP);
191
189 msg_size = 4 + 4 + 8 + 8 + 4+8; 192 msg_size = 4 + 4 + 8 + 8 + 4+8;
190 msg_size += 2 + 4 + 8 + 4 + 4; /* oloc */ 193 msg_size += 2 + 4 + 8 + 4 + 4; /* oloc */
191 msg_size += 1 + 8 + 4 + 4; /* pg_t */ 194 msg_size += 1 + 8 + 4 + 4; /* pg_t */
@@ -207,6 +210,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
207 210
208 req->r_osdc = osdc; 211 req->r_osdc = osdc;
209 req->r_mempool = use_mempool; 212 req->r_mempool = use_mempool;
213 req->r_num_ops = num_ops;
210 214
211 kref_init(&req->r_kref); 215 kref_init(&req->r_kref);
212 init_completion(&req->r_completion); 216 init_completion(&req->r_completion);
@@ -418,12 +422,14 @@ void osd_req_op_watch_init(struct ceph_osd_req_op *op, u16 opcode,
418EXPORT_SYMBOL(osd_req_op_watch_init); 422EXPORT_SYMBOL(osd_req_op_watch_init);
419 423
420static u64 osd_req_encode_op(struct ceph_osd_request *req, 424static u64 osd_req_encode_op(struct ceph_osd_request *req,
421 struct ceph_osd_op *dst, 425 struct ceph_osd_op *dst, unsigned int which)
422 struct ceph_osd_req_op *src)
423{ 426{
427 struct ceph_osd_req_op *src;
424 u64 out_data_len = 0; 428 u64 out_data_len = 0;
425 struct ceph_pagelist *pagelist; 429 struct ceph_pagelist *pagelist;
426 430
431 BUG_ON(which >= req->r_num_ops);
432 src = &req->r_ops[which];
427 if (WARN_ON(!osd_req_opcode_valid(src->op))) { 433 if (WARN_ON(!osd_req_opcode_valid(src->op))) {
428 pr_err("unrecognized osd opcode %d\n", src->op); 434 pr_err("unrecognized osd opcode %d\n", src->op);
429 435
@@ -487,21 +493,17 @@ static u64 osd_req_encode_op(struct ceph_osd_request *req,
487 * build new request AND message 493 * build new request AND message
488 * 494 *
489 */ 495 */
490void ceph_osdc_build_request(struct ceph_osd_request *req, 496void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off,
491 u64 off, unsigned int num_ops, 497 struct ceph_snap_context *snapc, u64 snap_id,
492 struct ceph_osd_req_op *src_ops, 498 struct timespec *mtime)
493 struct ceph_snap_context *snapc, u64 snap_id,
494 struct timespec *mtime)
495{ 499{
496 struct ceph_msg *msg = req->r_request; 500 struct ceph_msg *msg = req->r_request;
497 struct ceph_osd_req_op *src_op;
498 void *p; 501 void *p;
499 size_t msg_size; 502 size_t msg_size;
500 int flags = req->r_flags; 503 int flags = req->r_flags;
501 u64 data_len; 504 u64 data_len;
502 int i; 505 unsigned int i;
503 506
504 req->r_num_ops = num_ops;
505 req->r_snapid = snap_id; 507 req->r_snapid = snap_id;
506 req->r_snapc = ceph_get_snap_context(snapc); 508 req->r_snapc = ceph_get_snap_context(snapc);
507 509
@@ -541,12 +543,10 @@ void ceph_osdc_build_request(struct ceph_osd_request *req,
541 p += req->r_oid_len; 543 p += req->r_oid_len;
542 544
543 /* ops--can imply data */ 545 /* ops--can imply data */
544 ceph_encode_16(&p, num_ops); 546 ceph_encode_16(&p, (u16)req->r_num_ops);
545 src_op = src_ops;
546 req->r_request_ops = p;
547 data_len = 0; 547 data_len = 0;
548 for (i = 0; i < num_ops; i++, src_op++) { 548 for (i = 0; i < req->r_num_ops; i++) {
549 data_len += osd_req_encode_op(req, p, src_op); 549 data_len += osd_req_encode_op(req, p, i);
550 p += sizeof(struct ceph_osd_op); 550 p += sizeof(struct ceph_osd_op);
551 } 551 }
552 552
@@ -602,7 +602,6 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
602 struct ceph_file_layout *layout, 602 struct ceph_file_layout *layout,
603 struct ceph_vino vino, 603 struct ceph_vino vino,
604 u64 off, u64 *plen, int num_ops, 604 u64 off, u64 *plen, int num_ops,
605 struct ceph_osd_req_op *ops,
606 int opcode, int flags, 605 int opcode, int flags,
607 struct ceph_snap_context *snapc, 606 struct ceph_snap_context *snapc,
608 u32 truncate_seq, 607 u32 truncate_seq,
@@ -610,6 +609,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
610 bool use_mempool) 609 bool use_mempool)
611{ 610{
612 struct ceph_osd_request *req; 611 struct ceph_osd_request *req;
612 struct ceph_osd_req_op *op;
613 u64 objnum = 0; 613 u64 objnum = 0;
614 u64 objoff = 0; 614 u64 objoff = 0;
615 u64 objlen = 0; 615 u64 objlen = 0;
@@ -623,6 +623,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
623 GFP_NOFS); 623 GFP_NOFS);
624 if (!req) 624 if (!req)
625 return ERR_PTR(-ENOMEM); 625 return ERR_PTR(-ENOMEM);
626
626 req->r_flags = flags; 627 req->r_flags = flags;
627 628
628 /* calculate max write size */ 629 /* calculate max write size */
@@ -642,7 +643,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
642 truncate_size = object_size; 643 truncate_size = object_size;
643 } 644 }
644 645
645 osd_req_op_extent_init(&ops[0], opcode, objoff, objlen, 646 op = &req->r_ops[0];
647 osd_req_op_extent_init(op, opcode, objoff, objlen,
646 truncate_size, truncate_seq); 648 truncate_size, truncate_seq);
647 /* 649 /*
648 * A second op in the ops array means the caller wants to 650 * A second op in the ops array means the caller wants to
@@ -650,7 +652,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
650 * osd will flush data quickly. 652 * osd will flush data quickly.
651 */ 653 */
652 if (num_ops > 1) 654 if (num_ops > 1)
653 osd_req_op_init(&ops[1], CEPH_OSD_OP_STARTSYNC); 655 osd_req_op_init(++op, CEPH_OSD_OP_STARTSYNC);
654 656
655 req->r_file_layout = *layout; /* keep a copy */ 657 req->r_file_layout = *layout; /* keep a copy */
656 658
@@ -1342,7 +1344,8 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
1342 struct ceph_osd_request *req; 1344 struct ceph_osd_request *req;
1343 u64 tid; 1345 u64 tid;
1344 int object_len; 1346 int object_len;
1345 int numops, payload_len, flags; 1347 unsigned int numops;
1348 int payload_len, flags;
1346 s32 result; 1349 s32 result;
1347 s32 retry_attempt; 1350 s32 retry_attempt;
1348 struct ceph_pg pg; 1351 struct ceph_pg pg;
@@ -1352,7 +1355,7 @@ static void handle_reply(struct ceph_osd_client *osdc, struct ceph_msg *msg,
1352 u32 osdmap_epoch; 1355 u32 osdmap_epoch;
1353 int already_completed; 1356 int already_completed;
1354 u32 bytes; 1357 u32 bytes;
1355 int i; 1358 unsigned int i;
1356 1359
1357 tid = le64_to_cpu(msg->hdr.tid); 1360 tid = le64_to_cpu(msg->hdr.tid);
1358 dout("handle_reply %p tid %llu\n", msg, tid); 1361 dout("handle_reply %p tid %llu\n", msg, tid);
@@ -2116,12 +2119,11 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
2116 struct page **pages, int num_pages, int page_align) 2119 struct page **pages, int num_pages, int page_align)
2117{ 2120{
2118 struct ceph_osd_request *req; 2121 struct ceph_osd_request *req;
2119 struct ceph_osd_req_op op;
2120 int rc = 0; 2122 int rc = 0;
2121 2123
2122 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino, 2124 dout("readpages on ino %llx.%llx on %llu~%llu\n", vino.ino,
2123 vino.snap, off, *plen); 2125 vino.snap, off, *plen);
2124 req = ceph_osdc_new_request(osdc, layout, vino, off, plen, 1, &op, 2126 req = ceph_osdc_new_request(osdc, layout, vino, off, plen, 1,
2125 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, 2127 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
2126 NULL, truncate_seq, truncate_size, 2128 NULL, truncate_seq, truncate_size,
2127 false); 2129 false);
@@ -2136,7 +2138,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
2136 dout("readpages final extent is %llu~%llu (%llu bytes align %d)\n", 2138 dout("readpages final extent is %llu~%llu (%llu bytes align %d)\n",
2137 off, *plen, *plen, page_align); 2139 off, *plen, *plen, page_align);
2138 2140
2139 ceph_osdc_build_request(req, off, 1, &op, NULL, vino.snap, NULL); 2141 ceph_osdc_build_request(req, off, NULL, vino.snap, NULL);
2140 2142
2141 rc = ceph_osdc_start_request(osdc, req, false); 2143 rc = ceph_osdc_start_request(osdc, req, false);
2142 if (!rc) 2144 if (!rc)
@@ -2160,12 +2162,11 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
2160 struct page **pages, int num_pages) 2162 struct page **pages, int num_pages)
2161{ 2163{
2162 struct ceph_osd_request *req; 2164 struct ceph_osd_request *req;
2163 struct ceph_osd_req_op op;
2164 int rc = 0; 2165 int rc = 0;
2165 int page_align = off & ~PAGE_MASK; 2166 int page_align = off & ~PAGE_MASK;
2166 2167
2167 BUG_ON(vino.snap != CEPH_NOSNAP); /* snapshots aren't writeable */ 2168 BUG_ON(vino.snap != CEPH_NOSNAP); /* snapshots aren't writeable */
2168 req = ceph_osdc_new_request(osdc, layout, vino, off, &len, 1, &op, 2169 req = ceph_osdc_new_request(osdc, layout, vino, off, &len, 1,
2169 CEPH_OSD_OP_WRITE, 2170 CEPH_OSD_OP_WRITE,
2170 CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE, 2171 CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE,
2171 snapc, truncate_seq, truncate_size, 2172 snapc, truncate_seq, truncate_size,
@@ -2178,7 +2179,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
2178 false, false); 2179 false, false);
2179 dout("writepages %llu~%llu (%llu bytes)\n", off, len, len); 2180 dout("writepages %llu~%llu (%llu bytes)\n", off, len, len);
2180 2181
2181 ceph_osdc_build_request(req, off, 1, &op, snapc, CEPH_NOSNAP, mtime); 2182 ceph_osdc_build_request(req, off, snapc, CEPH_NOSNAP, mtime);
2182 2183
2183 rc = ceph_osdc_start_request(osdc, req, true); 2184 rc = ceph_osdc_start_request(osdc, req, true);
2184 if (!rc) 2185 if (!rc)