aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ceph/messenger.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 8bfe7d34bc85..84703e550c26 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -734,7 +734,7 @@ static void ceph_msg_data_bio_cursor_init(struct ceph_msg_data_cursor *cursor,
734 BUG_ON(!bio); 734 BUG_ON(!bio);
735 BUG_ON(!bio->bi_vcnt); 735 BUG_ON(!bio->bi_vcnt);
736 736
737 cursor->resid = length; 737 cursor->resid = min(length, data->bio_length);
738 cursor->bio = bio; 738 cursor->bio = bio;
739 cursor->vector_index = 0; 739 cursor->vector_index = 0;
740 cursor->vector_offset = 0; 740 cursor->vector_offset = 0;
@@ -833,9 +833,8 @@ static void ceph_msg_data_pages_cursor_init(struct ceph_msg_data_cursor *cursor,
833 833
834 BUG_ON(!data->pages); 834 BUG_ON(!data->pages);
835 BUG_ON(!data->length); 835 BUG_ON(!data->length);
836 BUG_ON(length > data->length); /* short reads are OK */
837 836
838 cursor->resid = length; 837 cursor->resid = min(length, data->length);
839 page_count = calc_pages_for(data->alignment, (u64)data->length); 838 page_count = calc_pages_for(data->alignment, (u64)data->length);
840 cursor->page_offset = data->alignment & ~PAGE_MASK; 839 cursor->page_offset = data->alignment & ~PAGE_MASK;
841 cursor->page_index = 0; 840 cursor->page_index = 0;
@@ -904,7 +903,6 @@ ceph_msg_data_pagelist_cursor_init(struct ceph_msg_data_cursor *cursor,
904 903
905 pagelist = data->pagelist; 904 pagelist = data->pagelist;
906 BUG_ON(!pagelist); 905 BUG_ON(!pagelist);
907 BUG_ON(length > pagelist->length); /* short reads are OK */
908 906
909 if (!length) 907 if (!length)
910 return; /* pagelist can be assigned but empty */ 908 return; /* pagelist can be assigned but empty */
@@ -912,7 +910,7 @@ ceph_msg_data_pagelist_cursor_init(struct ceph_msg_data_cursor *cursor,
912 BUG_ON(list_empty(&pagelist->head)); 910 BUG_ON(list_empty(&pagelist->head));
913 page = list_first_entry(&pagelist->head, struct page, lru); 911 page = list_first_entry(&pagelist->head, struct page, lru);
914 912
915 cursor->resid = length; 913 cursor->resid = min(length, pagelist->length);
916 cursor->page = page; 914 cursor->page = page;
917 cursor->offset = 0; 915 cursor->offset = 0;
918 cursor->last_piece = length <= PAGE_SIZE; 916 cursor->last_piece = length <= PAGE_SIZE;
@@ -982,13 +980,10 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data_cursor *cursor,
982 * be processed in that piece. It also tracks whether the current 980 * be processed in that piece. It also tracks whether the current
983 * piece is the last one in the data item. 981 * piece is the last one in the data item.
984 */ 982 */
985static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length) 983static void __ceph_msg_data_cursor_init(struct ceph_msg_data_cursor *cursor)
986{ 984{
987 struct ceph_msg_data_cursor *cursor = &msg->cursor; 985 size_t length = cursor->total_resid;
988 struct ceph_msg_data *data;
989 986
990 data = list_first_entry(&msg->data, struct ceph_msg_data, links);
991 cursor->data = data;
992 switch (cursor->data->type) { 987 switch (cursor->data->type) {
993 case CEPH_MSG_DATA_PAGELIST: 988 case CEPH_MSG_DATA_PAGELIST:
994 ceph_msg_data_pagelist_cursor_init(cursor, length); 989 ceph_msg_data_pagelist_cursor_init(cursor, length);
@@ -1009,6 +1004,25 @@ static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length)
1009 cursor->need_crc = true; 1004 cursor->need_crc = true;
1010} 1005}
1011 1006
1007static void ceph_msg_data_cursor_init(struct ceph_msg *msg, size_t length)
1008{
1009 struct ceph_msg_data_cursor *cursor = &msg->cursor;
1010 struct ceph_msg_data *data;
1011
1012 BUG_ON(!length);
1013 BUG_ON(length > msg->data_length);
1014 BUG_ON(list_empty(&msg->data));
1015
1016 data = list_first_entry(&msg->data, struct ceph_msg_data, links);
1017
1018 cursor->data_head = &msg->data;
1019 cursor->total_resid = length;
1020 data = list_first_entry(&msg->data, struct ceph_msg_data, links);
1021 cursor->data = data;
1022
1023 __ceph_msg_data_cursor_init(cursor);
1024}
1025
1012/* 1026/*
1013 * Return the page containing the next piece to process for a given 1027 * Return the page containing the next piece to process for a given
1014 * data item, and supply the page offset and length of that piece. 1028 * data item, and supply the page offset and length of that piece.
@@ -1073,8 +1087,16 @@ static bool ceph_msg_data_advance(struct ceph_msg_data_cursor *cursor,
1073 BUG(); 1087 BUG();
1074 break; 1088 break;
1075 } 1089 }
1090 cursor->total_resid -= bytes;
1076 cursor->need_crc = new_piece; 1091 cursor->need_crc = new_piece;
1077 1092
1093 if (!cursor->resid && cursor->total_resid) {
1094 WARN_ON(!cursor->last_piece);
1095 BUG_ON(list_is_last(&cursor->data->links, cursor->data_head));
1096 cursor->data = list_entry_next(cursor->data, links);
1097 __ceph_msg_data_cursor_init(cursor);
1098 }
1099
1078 return new_piece; 1100 return new_piece;
1079} 1101}
1080 1102
@@ -2990,8 +3012,6 @@ void ceph_msg_data_set_pages(struct ceph_msg *msg, struct page **pages,
2990 3012
2991 BUG_ON(!pages); 3013 BUG_ON(!pages);
2992 BUG_ON(!length); 3014 BUG_ON(!length);
2993 BUG_ON(msg->data_length);
2994 BUG_ON(!list_empty(&msg->data));
2995 3015
2996 data = ceph_msg_data_create(CEPH_MSG_DATA_PAGES); 3016 data = ceph_msg_data_create(CEPH_MSG_DATA_PAGES);
2997 BUG_ON(!data); 3017 BUG_ON(!data);
@@ -3012,8 +3032,6 @@ void ceph_msg_data_set_pagelist(struct ceph_msg *msg,
3012 3032
3013 BUG_ON(!pagelist); 3033 BUG_ON(!pagelist);
3014 BUG_ON(!pagelist->length); 3034 BUG_ON(!pagelist->length);
3015 BUG_ON(msg->data_length);
3016 BUG_ON(!list_empty(&msg->data));
3017 3035
3018 data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST); 3036 data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST);
3019 BUG_ON(!data); 3037 BUG_ON(!data);
@@ -3031,8 +3049,6 @@ void ceph_msg_data_set_bio(struct ceph_msg *msg, struct bio *bio,
3031 struct ceph_msg_data *data; 3049 struct ceph_msg_data *data;
3032 3050
3033 BUG_ON(!bio); 3051 BUG_ON(!bio);
3034 BUG_ON(msg->data_length);
3035 BUG_ON(!list_empty(&msg->data));
3036 3052
3037 data = ceph_msg_data_create(CEPH_MSG_DATA_BIO); 3053 data = ceph_msg_data_create(CEPH_MSG_DATA_BIO);
3038 BUG_ON(!data); 3054 BUG_ON(!data);