aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ceph/messenger.c61
-rw-r--r--net/ceph/mon_client.c3
-rw-r--r--net/ceph/osd_client.c1
3 files changed, 38 insertions, 27 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 3b65f6e6911b..98ca23726ea6 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1655,9 +1655,8 @@ static int read_partial_message_section(struct ceph_connection *con,
1655 return 1; 1655 return 1;
1656} 1656}
1657 1657
1658static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, 1658static bool ceph_con_in_msg_alloc(struct ceph_connection *con,
1659 struct ceph_msg_header *hdr, 1659 struct ceph_msg_header *hdr);
1660 int *skip);
1661 1660
1662 1661
1663static int read_partial_message_pages(struct ceph_connection *con, 1662static int read_partial_message_pages(struct ceph_connection *con,
@@ -1740,7 +1739,6 @@ static int read_partial_message(struct ceph_connection *con)
1740 int ret; 1739 int ret;
1741 unsigned front_len, middle_len, data_len; 1740 unsigned front_len, middle_len, data_len;
1742 bool do_datacrc = !con->msgr->nocrc; 1741 bool do_datacrc = !con->msgr->nocrc;
1743 int skip;
1744 u64 seq; 1742 u64 seq;
1745 u32 crc; 1743 u32 crc;
1746 1744
@@ -1793,9 +1791,7 @@ static int read_partial_message(struct ceph_connection *con)
1793 if (!con->in_msg) { 1791 if (!con->in_msg) {
1794 dout("got hdr type %d front %d data %d\n", con->in_hdr.type, 1792 dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
1795 con->in_hdr.front_len, con->in_hdr.data_len); 1793 con->in_hdr.front_len, con->in_hdr.data_len);
1796 skip = 0; 1794 if (ceph_con_in_msg_alloc(con, &con->in_hdr)) {
1797 con->in_msg = ceph_alloc_msg(con, &con->in_hdr, &skip);
1798 if (skip) {
1799 /* skip this message */ 1795 /* skip this message */
1800 dout("alloc_msg said skip message\n"); 1796 dout("alloc_msg said skip message\n");
1801 BUG_ON(con->in_msg); 1797 BUG_ON(con->in_msg);
@@ -2577,46 +2573,57 @@ static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
2577} 2573}
2578 2574
2579/* 2575/*
2580 * Generic message allocator, for incoming messages. 2576 * Allocate a message for receiving an incoming message on a
2577 * connection, and save the result in con->in_msg. Uses the
2578 * connection's private alloc_msg op if available.
2579 *
2580 * Returns true if the message should be skipped, false otherwise.
2581 * If true is returned (skip message), con->in_msg will be NULL.
2582 * If false is returned, con->in_msg will contain a pointer to the
2583 * newly-allocated message, or NULL in case of memory exhaustion.
2581 */ 2584 */
2582static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, 2585static bool ceph_con_in_msg_alloc(struct ceph_connection *con,
2583 struct ceph_msg_header *hdr, 2586 struct ceph_msg_header *hdr)
2584 int *skip)
2585{ 2587{
2586 int type = le16_to_cpu(hdr->type); 2588 int type = le16_to_cpu(hdr->type);
2587 int front_len = le32_to_cpu(hdr->front_len); 2589 int front_len = le32_to_cpu(hdr->front_len);
2588 int middle_len = le32_to_cpu(hdr->middle_len); 2590 int middle_len = le32_to_cpu(hdr->middle_len);
2589 struct ceph_msg *msg = NULL;
2590 int ret; 2591 int ret;
2591 2592
2593 BUG_ON(con->in_msg != NULL);
2594
2592 if (con->ops->alloc_msg) { 2595 if (con->ops->alloc_msg) {
2596 int skip = 0;
2597
2593 mutex_unlock(&con->mutex); 2598 mutex_unlock(&con->mutex);
2594 msg = con->ops->alloc_msg(con, hdr, skip); 2599 con->in_msg = con->ops->alloc_msg(con, hdr, &skip);
2595 mutex_lock(&con->mutex); 2600 mutex_lock(&con->mutex);
2596 if (!msg || *skip) 2601 if (skip)
2597 return NULL; 2602 con->in_msg = NULL;
2603
2604 if (!con->in_msg)
2605 return skip != 0;
2598 } 2606 }
2599 if (!msg) { 2607 if (!con->in_msg) {
2600 *skip = 0; 2608 con->in_msg = ceph_msg_new(type, front_len, GFP_NOFS, false);
2601 msg = ceph_msg_new(type, front_len, GFP_NOFS, false); 2609 if (!con->in_msg) {
2602 if (!msg) {
2603 pr_err("unable to allocate msg type %d len %d\n", 2610 pr_err("unable to allocate msg type %d len %d\n",
2604 type, front_len); 2611 type, front_len);
2605 return NULL; 2612 return false;
2606 } 2613 }
2607 msg->page_alignment = le16_to_cpu(hdr->data_off); 2614 con->in_msg->page_alignment = le16_to_cpu(hdr->data_off);
2608 } 2615 }
2609 memcpy(&msg->hdr, &con->in_hdr, sizeof(con->in_hdr)); 2616 memcpy(&con->in_msg->hdr, &con->in_hdr, sizeof(con->in_hdr));
2610 2617
2611 if (middle_len && !msg->middle) { 2618 if (middle_len && !con->in_msg->middle) {
2612 ret = ceph_alloc_middle(con, msg); 2619 ret = ceph_alloc_middle(con, con->in_msg);
2613 if (ret < 0) { 2620 if (ret < 0) {
2614 ceph_msg_put(msg); 2621 ceph_msg_put(con->in_msg);
2615 return NULL; 2622 con->in_msg = NULL;
2616 } 2623 }
2617 } 2624 }
2618 2625
2619 return msg; 2626 return false;
2620} 2627}
2621 2628
2622 2629
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index ab6b24a5169e..8462ccec6333 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -442,6 +442,7 @@ static struct ceph_msg *get_generic_reply(struct ceph_connection *con,
442 m = NULL; 442 m = NULL;
443 } else { 443 } else {
444 dout("get_generic_reply %lld got %p\n", tid, req->reply); 444 dout("get_generic_reply %lld got %p\n", tid, req->reply);
445 *skip = 0;
445 m = ceph_msg_get(req->reply); 446 m = ceph_msg_get(req->reply);
446 /* 447 /*
447 * we don't need to track the connection reading into 448 * we don't need to track the connection reading into
@@ -982,6 +983,8 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
982 case CEPH_MSG_MDS_MAP: 983 case CEPH_MSG_MDS_MAP:
983 case CEPH_MSG_OSD_MAP: 984 case CEPH_MSG_OSD_MAP:
984 m = ceph_msg_new(type, front_len, GFP_NOFS, false); 985 m = ceph_msg_new(type, front_len, GFP_NOFS, false);
986 if (!m)
987 return NULL; /* ENOMEM--return skip == 0 */
985 break; 988 break;
986 } 989 }
987 990
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 448c9da8beff..24b427b1eca4 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -2077,6 +2077,7 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con,
2077 int type = le16_to_cpu(hdr->type); 2077 int type = le16_to_cpu(hdr->type);
2078 int front = le32_to_cpu(hdr->front_len); 2078 int front = le32_to_cpu(hdr->front_len);
2079 2079
2080 *skip = 0;
2080 switch (type) { 2081 switch (type) {
2081 case CEPH_MSG_OSD_MAP: 2082 case CEPH_MSG_OSD_MAP:
2082 case CEPH_MSG_WATCH_NOTIFY: 2083 case CEPH_MSG_WATCH_NOTIFY: