aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/block/rbd.c18
-rw-r--r--fs/ceph/addr.c8
-rw-r--r--fs/ceph/file.c7
-rw-r--r--include/linux/ceph/osd_client.h1
-rw-r--r--net/ceph/osd_client.c88
5 files changed, 82 insertions, 40 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index c3089f32a392..bda4deade82e 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1954,7 +1954,7 @@ static struct ceph_osd_request *rbd_osd_req_create(
1954 osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false, 1954 osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false,
1955 GFP_NOIO); 1955 GFP_NOIO);
1956 if (!osd_req) 1956 if (!osd_req)
1957 return NULL; /* ENOMEM */ 1957 goto fail;
1958 1958
1959 if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD) 1959 if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD)
1960 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; 1960 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK;
@@ -1967,7 +1967,14 @@ static struct ceph_osd_request *rbd_osd_req_create(
1967 osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout); 1967 osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
1968 ceph_oid_set_name(&osd_req->r_base_oid, obj_request->object_name); 1968 ceph_oid_set_name(&osd_req->r_base_oid, obj_request->object_name);
1969 1969
1970 if (ceph_osdc_alloc_messages(osd_req, GFP_NOIO))
1971 goto fail;
1972
1970 return osd_req; 1973 return osd_req;
1974
1975fail:
1976 ceph_osdc_put_request(osd_req);
1977 return NULL;
1971} 1978}
1972 1979
1973/* 1980/*
@@ -2003,7 +2010,7 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
2003 osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops, 2010 osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops,
2004 false, GFP_NOIO); 2011 false, GFP_NOIO);
2005 if (!osd_req) 2012 if (!osd_req)
2006 return NULL; /* ENOMEM */ 2013 goto fail;
2007 2014
2008 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; 2015 osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK;
2009 osd_req->r_callback = rbd_osd_req_callback; 2016 osd_req->r_callback = rbd_osd_req_callback;
@@ -2012,7 +2019,14 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request)
2012 osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout); 2019 osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
2013 ceph_oid_set_name(&osd_req->r_base_oid, obj_request->object_name); 2020 ceph_oid_set_name(&osd_req->r_base_oid, obj_request->object_name);
2014 2021
2022 if (ceph_osdc_alloc_messages(osd_req, GFP_NOIO))
2023 goto fail;
2024
2015 return osd_req; 2025 return osd_req;
2026
2027fail:
2028 ceph_osdc_put_request(osd_req);
2029 return NULL;
2016} 2030}
2017 2031
2018 2032
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 3e61fc8bb371..6fee7e0b8931 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1762,6 +1762,10 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool)
1762 "%llx.00000000", ci->i_vino.ino); 1762 "%llx.00000000", ci->i_vino.ino);
1763 rd_req->r_base_oid.name_len = strlen(rd_req->r_base_oid.name); 1763 rd_req->r_base_oid.name_len = strlen(rd_req->r_base_oid.name);
1764 1764
1765 err = ceph_osdc_alloc_messages(rd_req, GFP_NOFS);
1766 if (err)
1767 goto out_unlock;
1768
1765 wr_req = ceph_osdc_alloc_request(&fsc->client->osdc, NULL, 1769 wr_req = ceph_osdc_alloc_request(&fsc->client->osdc, NULL,
1766 1, false, GFP_NOFS); 1770 1, false, GFP_NOFS);
1767 if (!wr_req) { 1771 if (!wr_req) {
@@ -1775,6 +1779,10 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool)
1775 wr_req->r_base_oloc.pool = pool; 1779 wr_req->r_base_oloc.pool = pool;
1776 wr_req->r_base_oid = rd_req->r_base_oid; 1780 wr_req->r_base_oid = rd_req->r_base_oid;
1777 1781
1782 err = ceph_osdc_alloc_messages(wr_req, GFP_NOFS);
1783 if (err)
1784 goto out_unlock;
1785
1778 /* one page should be large enough for STAT data */ 1786 /* one page should be large enough for STAT data */
1779 pages = ceph_alloc_page_vector(1, GFP_KERNEL); 1787 pages = ceph_alloc_page_vector(1, GFP_KERNEL);
1780 if (IS_ERR(pages)) { 1788 if (IS_ERR(pages)) {
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index a79f9269831e..5d46d106bbb7 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -717,6 +717,13 @@ static void ceph_aio_retry_work(struct work_struct *work)
717 req->r_base_oloc = orig_req->r_base_oloc; 717 req->r_base_oloc = orig_req->r_base_oloc;
718 req->r_base_oid = orig_req->r_base_oid; 718 req->r_base_oid = orig_req->r_base_oid;
719 719
720 ret = ceph_osdc_alloc_messages(req, GFP_NOFS);
721 if (ret) {
722 ceph_osdc_put_request(req);
723 req = orig_req;
724 goto out;
725 }
726
720 req->r_ops[0] = orig_req->r_ops[0]; 727 req->r_ops[0] = orig_req->r_ops[0];
721 osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0); 728 osd_req_op_init(req, 1, CEPH_OSD_OP_STARTSYNC, 0);
722 729
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index cbf460927c42..66a1fcd5bff7 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -322,6 +322,7 @@ extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *
322 unsigned int num_ops, 322 unsigned int num_ops,
323 bool use_mempool, 323 bool use_mempool,
324 gfp_t gfp_flags); 324 gfp_t gfp_flags);
325int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp);
325 326
326extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, 327extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off,
327 struct ceph_snap_context *snapc, 328 struct ceph_snap_context *snapc,
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index ccb9539dc780..d66dacc9d0d4 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -369,8 +369,6 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
369 gfp_t gfp_flags) 369 gfp_t gfp_flags)
370{ 370{
371 struct ceph_osd_request *req; 371 struct ceph_osd_request *req;
372 struct ceph_msg *msg;
373 size_t msg_size;
374 372
375 if (use_mempool) { 373 if (use_mempool) {
376 BUG_ON(num_ops > CEPH_OSD_SLAB_OPS); 374 BUG_ON(num_ops > CEPH_OSD_SLAB_OPS);
@@ -407,53 +405,59 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc,
407 req->r_base_oloc.pool = -1; 405 req->r_base_oloc.pool = -1;
408 req->r_target_oloc.pool = -1; 406 req->r_target_oloc.pool = -1;
409 407
410 msg_size = OSD_OPREPLY_FRONT_LEN; 408 dout("%s req %p\n", __func__, req);
411 if (num_ops > CEPH_OSD_SLAB_OPS) { 409 return req;
412 /* ceph_osd_op and rval */ 410}
413 msg_size += (num_ops - CEPH_OSD_SLAB_OPS) * 411EXPORT_SYMBOL(ceph_osdc_alloc_request);
414 (sizeof(struct ceph_osd_op) + 4);
415 }
416 412
417 /* create reply message */ 413int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp)
418 if (use_mempool) 414{
419 msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0); 415 struct ceph_osd_client *osdc = req->r_osdc;
420 else 416 struct ceph_msg *msg;
421 msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, msg_size, 417 int msg_size;
422 gfp_flags, true);
423 if (!msg) {
424 ceph_osdc_put_request(req);
425 return NULL;
426 }
427 req->r_reply = msg;
428 418
419 /* create request message */
429 msg_size = 4 + 4 + 4; /* client_inc, osdmap_epoch, flags */ 420 msg_size = 4 + 4 + 4; /* client_inc, osdmap_epoch, flags */
430 msg_size += 4 + 4 + 4 + 8; /* mtime, reassert_version */ 421 msg_size += 4 + 4 + 4 + 8; /* mtime, reassert_version */
431 msg_size += 2 + 4 + 8 + 4 + 4; /* oloc */ 422 msg_size += 2 + 4 + 8 + 4 + 4; /* oloc */
432 msg_size += 1 + 8 + 4 + 4; /* pgid */ 423 msg_size += 1 + 8 + 4 + 4; /* pgid */
433 msg_size += 4 + CEPH_MAX_OID_NAME_LEN; /* oid */ 424 msg_size += 4 + req->r_base_oid.name_len; /* oid */
434 msg_size += 2 + num_ops * sizeof(struct ceph_osd_op); 425 msg_size += 2 + req->r_num_ops * sizeof(struct ceph_osd_op);
435 msg_size += 8; /* snapid */ 426 msg_size += 8; /* snapid */
436 msg_size += 8; /* snap_seq */ 427 msg_size += 8; /* snap_seq */
437 msg_size += 4 + 8 * (snapc ? snapc->num_snaps : 0); /* snaps */ 428 msg_size += 4 + 8 * (req->r_snapc ? req->r_snapc->num_snaps : 0);
438 msg_size += 4; /* retry_attempt */ 429 msg_size += 4; /* retry_attempt */
439 430
440 /* create request message; allow space for oid */ 431 if (req->r_mempool)
441 if (use_mempool)
442 msg = ceph_msgpool_get(&osdc->msgpool_op, 0); 432 msg = ceph_msgpool_get(&osdc->msgpool_op, 0);
443 else 433 else
444 msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp_flags, true); 434 msg = ceph_msg_new(CEPH_MSG_OSD_OP, msg_size, gfp, true);
445 if (!msg) { 435 if (!msg)
446 ceph_osdc_put_request(req); 436 return -ENOMEM;
447 return NULL;
448 }
449 437
450 memset(msg->front.iov_base, 0, msg->front.iov_len); 438 memset(msg->front.iov_base, 0, msg->front.iov_len);
451
452 req->r_request = msg; 439 req->r_request = msg;
453 440
454 return req; 441 /* create reply message */
442 msg_size = OSD_OPREPLY_FRONT_LEN;
443 if (req->r_num_ops > CEPH_OSD_SLAB_OPS) {
444 /* ceph_osd_op and rval */
445 msg_size += (req->r_num_ops - CEPH_OSD_SLAB_OPS) *
446 (sizeof(struct ceph_osd_op) + 4);
447 }
448
449 if (req->r_mempool)
450 msg = ceph_msgpool_get(&osdc->msgpool_op_reply, 0);
451 else
452 msg = ceph_msg_new(CEPH_MSG_OSD_OPREPLY, msg_size, gfp, true);
453 if (!msg)
454 return -ENOMEM;
455
456 req->r_reply = msg;
457
458 return 0;
455} 459}
456EXPORT_SYMBOL(ceph_osdc_alloc_request); 460EXPORT_SYMBOL(ceph_osdc_alloc_messages);
457 461
458static bool osd_req_opcode_valid(u16 opcode) 462static bool osd_req_opcode_valid(u16 opcode)
459{ 463{
@@ -828,17 +832,17 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
828 832
829 req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool, 833 req = ceph_osdc_alloc_request(osdc, snapc, num_ops, use_mempool,
830 GFP_NOFS); 834 GFP_NOFS);
831 if (!req) 835 if (!req) {
832 return ERR_PTR(-ENOMEM); 836 r = -ENOMEM;
837 goto fail;
838 }
833 839
834 req->r_flags = flags; 840 req->r_flags = flags;
835 841
836 /* calculate max write size */ 842 /* calculate max write size */
837 r = calc_layout(layout, off, plen, &objnum, &objoff, &objlen); 843 r = calc_layout(layout, off, plen, &objnum, &objoff, &objlen);
838 if (r < 0) { 844 if (r)
839 ceph_osdc_put_request(req); 845 goto fail;
840 return ERR_PTR(r);
841 }
842 846
843 if (opcode == CEPH_OSD_OP_CREATE || opcode == CEPH_OSD_OP_DELETE) { 847 if (opcode == CEPH_OSD_OP_CREATE || opcode == CEPH_OSD_OP_DELETE) {
844 osd_req_op_init(req, which, opcode, 0); 848 osd_req_op_init(req, which, opcode, 0);
@@ -864,7 +868,15 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
864 "%llx.%08llx", vino.ino, objnum); 868 "%llx.%08llx", vino.ino, objnum);
865 req->r_base_oid.name_len = strlen(req->r_base_oid.name); 869 req->r_base_oid.name_len = strlen(req->r_base_oid.name);
866 870
871 r = ceph_osdc_alloc_messages(req, GFP_NOFS);
872 if (r)
873 goto fail;
874
867 return req; 875 return req;
876
877fail:
878 ceph_osdc_put_request(req);
879 return ERR_PTR(r);
868} 880}
869EXPORT_SYMBOL(ceph_osdc_new_request); 881EXPORT_SYMBOL(ceph_osdc_new_request);
870 882