diff options
author | Alex Elder <elder@inktank.com> | 2013-03-30 16:09:59 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:17:39 -0400 |
commit | 5df521b1eecf276c4bae8ffb7945acef45530449 (patch) | |
tree | b6a8434361e786d81b364aa202cc40628eb60b65 /net | |
parent | 1190bf06a6b033384a65b5acdb1193d41cd257a6 (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')
-rw-r--r-- | net/ceph/messenger.c | 14 |
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 | ||