aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osd_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ceph/osd_client.c')
-rw-r--r--net/ceph/osd_client.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 79391994b3ed..6c096239660c 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -71,6 +71,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
71 op->extent.length = objlen; 71 op->extent.length = objlen;
72 } 72 }
73 req->r_num_pages = calc_pages_for(off, *plen); 73 req->r_num_pages = calc_pages_for(off, *plen);
74 req->r_page_alignment = off & ~PAGE_MASK;
74 if (op->op == CEPH_OSD_OP_WRITE) 75 if (op->op == CEPH_OSD_OP_WRITE)
75 op->payload_len = *plen; 76 op->payload_len = *plen;
76 77
@@ -419,7 +420,8 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
419 u32 truncate_seq, 420 u32 truncate_seq,
420 u64 truncate_size, 421 u64 truncate_size,
421 struct timespec *mtime, 422 struct timespec *mtime,
422 bool use_mempool, int num_reply) 423 bool use_mempool, int num_reply,
424 int page_align)
423{ 425{
424 struct ceph_osd_req_op ops[3]; 426 struct ceph_osd_req_op ops[3];
425 struct ceph_osd_request *req; 427 struct ceph_osd_request *req;
@@ -447,6 +449,10 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
447 calc_layout(osdc, vino, layout, off, plen, req, ops); 449 calc_layout(osdc, vino, layout, off, plen, req, ops);
448 req->r_file_layout = *layout; /* keep a copy */ 450 req->r_file_layout = *layout; /* keep a copy */
449 451
452 /* in case it differs from natural alignment that calc_layout
453 filled in for us */
454 req->r_page_alignment = page_align;
455
450 ceph_osdc_build_request(req, off, plen, ops, 456 ceph_osdc_build_request(req, off, plen, ops,
451 snapc, 457 snapc,
452 mtime, 458 mtime,
@@ -1489,7 +1495,7 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1489 struct ceph_vino vino, struct ceph_file_layout *layout, 1495 struct ceph_vino vino, struct ceph_file_layout *layout,
1490 u64 off, u64 *plen, 1496 u64 off, u64 *plen,
1491 u32 truncate_seq, u64 truncate_size, 1497 u32 truncate_seq, u64 truncate_size,
1492 struct page **pages, int num_pages) 1498 struct page **pages, int num_pages, int page_align)
1493{ 1499{
1494 struct ceph_osd_request *req; 1500 struct ceph_osd_request *req;
1495 int rc = 0; 1501 int rc = 0;
@@ -1499,15 +1505,15 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc,
1499 req = ceph_osdc_new_request(osdc, layout, vino, off, plen, 1505 req = ceph_osdc_new_request(osdc, layout, vino, off, plen,
1500 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, 1506 CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
1501 NULL, 0, truncate_seq, truncate_size, NULL, 1507 NULL, 0, truncate_seq, truncate_size, NULL,
1502 false, 1); 1508 false, 1, page_align);
1503 if (!req) 1509 if (!req)
1504 return -ENOMEM; 1510 return -ENOMEM;
1505 1511
1506 /* it may be a short read due to an object boundary */ 1512 /* it may be a short read due to an object boundary */
1507 req->r_pages = pages; 1513 req->r_pages = pages;
1508 1514
1509 dout("readpages final extent is %llu~%llu (%d pages)\n", 1515 dout("readpages final extent is %llu~%llu (%d pages align %d)\n",
1510 off, *plen, req->r_num_pages); 1516 off, *plen, req->r_num_pages, page_align);
1511 1517
1512 rc = ceph_osdc_start_request(osdc, req, false); 1518 rc = ceph_osdc_start_request(osdc, req, false);
1513 if (!rc) 1519 if (!rc)
@@ -1533,6 +1539,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1533{ 1539{
1534 struct ceph_osd_request *req; 1540 struct ceph_osd_request *req;
1535 int rc = 0; 1541 int rc = 0;
1542 int page_align = off & ~PAGE_MASK;
1536 1543
1537 BUG_ON(vino.snap != CEPH_NOSNAP); 1544 BUG_ON(vino.snap != CEPH_NOSNAP);
1538 req = ceph_osdc_new_request(osdc, layout, vino, off, &len, 1545 req = ceph_osdc_new_request(osdc, layout, vino, off, &len,
@@ -1541,7 +1548,7 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino,
1541 CEPH_OSD_FLAG_WRITE, 1548 CEPH_OSD_FLAG_WRITE,
1542 snapc, do_sync, 1549 snapc, do_sync,
1543 truncate_seq, truncate_size, mtime, 1550 truncate_seq, truncate_size, mtime,
1544 nofail, 1); 1551 nofail, 1, page_align);
1545 if (!req) 1552 if (!req)
1546 return -ENOMEM; 1553 return -ENOMEM;
1547 1554
@@ -1638,8 +1645,7 @@ static struct ceph_msg *get_reply(struct ceph_connection *con,
1638 m = ceph_msg_get(req->r_reply); 1645 m = ceph_msg_get(req->r_reply);
1639 1646
1640 if (data_len > 0) { 1647 if (data_len > 0) {
1641 unsigned data_off = le16_to_cpu(hdr->data_off); 1648 int want = calc_pages_for(req->r_page_alignment, data_len);
1642 int want = calc_pages_for(data_off & ~PAGE_MASK, data_len);
1643 1649
1644 if (unlikely(req->r_num_pages < want)) { 1650 if (unlikely(req->r_num_pages < want)) {
1645 pr_warning("tid %lld reply %d > expected %d pages\n", 1651 pr_warning("tid %lld reply %d > expected %d pages\n",