diff options
-rw-r--r-- | net/ceph/messenger.c | 56 |
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 | ||
1736 | static bool ceph_con_in_msg_alloc(struct ceph_connection *con, | 1736 | static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip); |
1737 | struct ceph_msg_header *hdr); | ||
1738 | |||
1739 | 1737 | ||
1740 | static int read_partial_message_pages(struct ceph_connection *con, | 1738 | static 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 | */ |
2723 | static bool ceph_con_in_msg_alloc(struct ceph_connection *con, | 2727 | static 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 | ||