aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/messenger.c
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-03-30 16:09:59 -0400
committerSage Weil <sage@inktank.com>2013-05-02 00:17:39 -0400
commit5df521b1eecf276c4bae8ffb7945acef45530449 (patch)
treeb6a8434361e786d81b364aa202cc40628eb60b65 /net/ceph/messenger.c
parent1190bf06a6b033384a65b5acdb1193d41cd257a6 (diff)
libceph: page offset must be less than page size
Currently ceph_msg_data_pages_advance() allows the page offset value to be PAGE_SIZE, apparently assuming ceph_msg_data_pages_next() will treat it as 0. But that doesn't happen, and the result led to a helpful assertion failure. Change ceph_msg_data_pages_advance() to truncate the offset to 0 before returning if it reaches PAGE_SIZE. Make a few other minor adjustments in this area (comments and a better assertion) while modifying it. This resolves a second issue described in: http://tracker.ceph.com/issues/4598 Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'net/ceph/messenger.c')
-rw-r--r--net/ceph/messenger.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 24f3aba34800..198b9026288e 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -766,8 +766,8 @@ static struct page *ceph_msg_data_bio_next(struct ceph_msg_data *data,
766 *length = cursor->resid; 766 *length = cursor->resid;
767 else 767 else
768 *length = (size_t) (bio_vec->bv_len - cursor->vector_offset); 768 *length = (size_t) (bio_vec->bv_len - cursor->vector_offset);
769 BUG_ON(*length > PAGE_SIZE);
770 BUG_ON(*length > cursor->resid); 769 BUG_ON(*length > cursor->resid);
770 BUG_ON(*page_offset + *length > PAGE_SIZE);
771 771
772 return bio_vec->bv_page; 772 return bio_vec->bv_page;
773} 773}
@@ -876,14 +876,13 @@ static bool ceph_msg_data_pages_advance(struct ceph_msg_data *data,
876 /* Advance the cursor page offset */ 876 /* Advance the cursor page offset */
877 877
878 cursor->resid -= bytes; 878 cursor->resid -= bytes;
879 cursor->page_offset += bytes; 879 cursor->page_offset = (cursor->page_offset + bytes) & ~PAGE_MASK;
880 if (!bytes || cursor->page_offset & ~PAGE_MASK) 880 if (!bytes || cursor->page_offset)
881 return false; /* more bytes to process in the current page */ 881 return false; /* more bytes to process in the current page */
882 882
883 /* Move on to the next page */ 883 /* Move on to the next page; offset is already at 0 */
884 884
885 BUG_ON(cursor->page_index >= cursor->page_count); 885 BUG_ON(cursor->page_index >= cursor->page_count);
886 cursor->page_offset = 0;
887 cursor->page_index++; 886 cursor->page_index++;
888 cursor->last_piece = cursor->resid <= PAGE_SIZE; 887 cursor->last_piece = cursor->resid <= PAGE_SIZE;
889 888
@@ -934,8 +933,9 @@ static struct page *ceph_msg_data_pagelist_next(struct ceph_msg_data *data,
934 BUG_ON(!cursor->page); 933 BUG_ON(!cursor->page);
935 BUG_ON(cursor->offset + cursor->resid != pagelist->length); 934 BUG_ON(cursor->offset + cursor->resid != pagelist->length);
936 935
936 /* offset of first page in pagelist is always 0 */
937 *page_offset = cursor->offset & ~PAGE_MASK; 937 *page_offset = cursor->offset & ~PAGE_MASK;
938 if (cursor->last_piece) /* pagelist offset is always 0 */ 938 if (cursor->last_piece)
939 *length = cursor->resid; 939 *length = cursor->resid;
940 else 940 else
941 *length = PAGE_SIZE - *page_offset; 941 *length = PAGE_SIZE - *page_offset;
@@ -961,7 +961,7 @@ static bool ceph_msg_data_pagelist_advance(struct ceph_msg_data *data,
961 961
962 cursor->resid -= bytes; 962 cursor->resid -= bytes;
963 cursor->offset += bytes; 963 cursor->offset += bytes;
964 /* pagelist offset is always 0 */ 964 /* offset of first page in pagelist is always 0 */
965 if (!bytes || cursor->offset & ~PAGE_MASK) 965 if (!bytes || cursor->offset & ~PAGE_MASK)
966 return false; /* more bytes to process in the current page */ 966 return false; /* more bytes to process in the current page */
967 967