diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/messenger.c | 61 | ||||
-rw-r--r-- | net/ceph/mon_client.c | 3 | ||||
-rw-r--r-- | net/ceph/osd_client.c | 1 |
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 | ||
1658 | static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, | 1658 | static 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 | ||
1663 | static int read_partial_message_pages(struct ceph_connection *con, | 1662 | static 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 | */ |
2582 | static struct ceph_msg *ceph_alloc_msg(struct ceph_connection *con, | 2585 | static 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: |