aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ceph/messenger.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index c3b628c76194..13b549b6b1bf 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1733,9 +1733,7 @@ static int read_partial_message_section(struct ceph_connection *con,
1733 return 1; 1733 return 1;
1734} 1734}
1735 1735
1736static bool ceph_con_in_msg_alloc(struct ceph_connection *con, 1736static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip);
1737 struct ceph_msg_header *hdr);
1738
1739 1737
1740static int read_partial_message_pages(struct ceph_connection *con, 1738static int read_partial_message_pages(struct ceph_connection *con,
1741 struct page **pages, 1739 struct page **pages,
@@ -1864,9 +1862,14 @@ static int read_partial_message(struct ceph_connection *con)
1864 1862
1865 /* allocate message? */ 1863 /* allocate message? */
1866 if (!con->in_msg) { 1864 if (!con->in_msg) {
1865 int skip = 0;
1866
1867 dout("got hdr type %d front %d data %d\n", con->in_hdr.type, 1867 dout("got hdr type %d front %d data %d\n", con->in_hdr.type,
1868 con->in_hdr.front_len, con->in_hdr.data_len); 1868 con->in_hdr.front_len, con->in_hdr.data_len);
1869 if (ceph_con_in_msg_alloc(con, &con->in_hdr)) { 1869 ret = ceph_con_in_msg_alloc(con, &skip);
1870 if (ret < 0)
1871 return ret;
1872 if (skip) {
1870 /* skip this message */ 1873 /* skip this message */
1871 dout("alloc_msg said skip message\n"); 1874 dout("alloc_msg said skip message\n");
1872 BUG_ON(con->in_msg); 1875 BUG_ON(con->in_msg);
@@ -1876,12 +1879,8 @@ static int read_partial_message(struct ceph_connection *con)
1876 con->in_seq++; 1879 con->in_seq++;
1877 return 0; 1880 return 0;
1878 } 1881 }
1879 if (!con->in_msg) {
1880 con->error_msg =
1881 "error allocating memory for incoming message";
1882 return -ENOMEM;
1883 }
1884 1882
1883 BUG_ON(!con->in_msg);
1885 BUG_ON(con->in_msg->con != con); 1884 BUG_ON(con->in_msg->con != con);
1886 m = con->in_msg; 1885 m = con->in_msg;
1887 m->front.iov_len = 0; /* haven't read it yet */ 1886 m->front.iov_len = 0; /* haven't read it yet */
@@ -2715,43 +2714,50 @@ static int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg)
2715 * connection, and save the result in con->in_msg. Uses the 2714 * connection, and save the result in con->in_msg. Uses the
2716 * connection's private alloc_msg op if available. 2715 * connection's private alloc_msg op if available.
2717 * 2716 *
2718 * Returns true if the message should be skipped, false otherwise. 2717 * Returns 0 on success, or a negative error code.
2719 * If true is returned (skip message), con->in_msg will be NULL. 2718 *
2720 * If false is returned, con->in_msg will contain a pointer to the 2719 * On success, if we set *skip = 1:
2721 * newly-allocated message, or NULL in case of memory exhaustion. 2720 * - the next message should be skipped and ignored.
2721 * - con->in_msg == NULL
2722 * or if we set *skip = 0:
2723 * - con->in_msg is non-null.
2724 * On error (ENOMEM, EAGAIN, ...),
2725 * - con->in_msg == NULL
2722 */ 2726 */
2723static bool ceph_con_in_msg_alloc(struct ceph_connection *con, 2727static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip)
2724 struct ceph_msg_header *hdr)
2725{ 2728{
2729 struct ceph_msg_header *hdr = &con->in_hdr;
2726 int type = le16_to_cpu(hdr->type); 2730 int type = le16_to_cpu(hdr->type);
2727 int front_len = le32_to_cpu(hdr->front_len); 2731 int front_len = le32_to_cpu(hdr->front_len);
2728 int middle_len = le32_to_cpu(hdr->middle_len); 2732 int middle_len = le32_to_cpu(hdr->middle_len);
2729 int ret; 2733 int ret = 0;
2730 2734
2731 BUG_ON(con->in_msg != NULL); 2735 BUG_ON(con->in_msg != NULL);
2732 2736
2733 if (con->ops->alloc_msg) { 2737 if (con->ops->alloc_msg) {
2734 int skip = 0;
2735
2736 mutex_unlock(&con->mutex); 2738 mutex_unlock(&con->mutex);
2737 con->in_msg = con->ops->alloc_msg(con, hdr, &skip); 2739 con->in_msg = con->ops->alloc_msg(con, hdr, skip);
2738 mutex_lock(&con->mutex); 2740 mutex_lock(&con->mutex);
2739 if (con->in_msg) { 2741 if (con->in_msg) {
2740 con->in_msg->con = con->ops->get(con); 2742 con->in_msg->con = con->ops->get(con);
2741 BUG_ON(con->in_msg->con == NULL); 2743 BUG_ON(con->in_msg->con == NULL);
2742 } 2744 }
2743 if (skip) 2745 if (*skip) {
2744 con->in_msg = NULL; 2746 con->in_msg = NULL;
2745 2747 return 0;
2746 if (!con->in_msg) 2748 }
2747 return skip != 0; 2749 if (!con->in_msg) {
2750 con->error_msg =
2751 "error allocating memory for incoming message";
2752 return -ENOMEM;
2753 }
2748 } 2754 }
2749 if (!con->in_msg) { 2755 if (!con->in_msg) {
2750 con->in_msg = ceph_msg_new(type, front_len, GFP_NOFS, false); 2756 con->in_msg = ceph_msg_new(type, front_len, GFP_NOFS, false);
2751 if (!con->in_msg) { 2757 if (!con->in_msg) {
2752 pr_err("unable to allocate msg type %d len %d\n", 2758 pr_err("unable to allocate msg type %d len %d\n",
2753 type, front_len); 2759 type, front_len);
2754 return false; 2760 return -ENOMEM;
2755 } 2761 }
2756 con->in_msg->con = con->ops->get(con); 2762 con->in_msg->con = con->ops->get(con);
2757 BUG_ON(con->in_msg->con == NULL); 2763 BUG_ON(con->in_msg->con == NULL);
@@ -2767,7 +2773,7 @@ static bool ceph_con_in_msg_alloc(struct ceph_connection *con,
2767 } 2773 }
2768 } 2774 }
2769 2775
2770 return false; 2776 return ret;
2771} 2777}
2772 2778
2773 2779