diff options
| -rw-r--r-- | drivers/block/rbd.c | 18 | ||||
| -rw-r--r-- | fs/ceph/addr.c | 8 | ||||
| -rw-r--r-- | fs/ceph/file.c | 7 | ||||
| -rw-r--r-- | include/linux/ceph/osd_client.h | 1 | ||||
| -rw-r--r-- | net/ceph/osd_client.c | 88 |
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 | |||
| 1975 | fail: | ||
| 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 | |||
| 2027 | fail: | ||
| 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); |
| 325 | int ceph_osdc_alloc_messages(struct ceph_osd_request *req, gfp_t gfp); | ||
| 325 | 326 | ||
| 326 | extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, | 327 | extern 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) * | 411 | EXPORT_SYMBOL(ceph_osdc_alloc_request); |
| 414 | (sizeof(struct ceph_osd_op) + 4); | ||
| 415 | } | ||
| 416 | 412 | ||
| 417 | /* create reply message */ | 413 | int 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 | } |
| 456 | EXPORT_SYMBOL(ceph_osdc_alloc_request); | 460 | EXPORT_SYMBOL(ceph_osdc_alloc_messages); |
| 457 | 461 | ||
| 458 | static bool osd_req_opcode_valid(u16 opcode) | 462 | static 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 | |||
| 877 | fail: | ||
| 878 | ceph_osdc_put_request(req); | ||
| 879 | return ERR_PTR(r); | ||
| 868 | } | 880 | } |
| 869 | EXPORT_SYMBOL(ceph_osdc_new_request); | 881 | EXPORT_SYMBOL(ceph_osdc_new_request); |
| 870 | 882 | ||
