|
@@ -1024,6 +1024,7 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
|
|
|
unsigned long buf_offset;
|
|
|
unsigned long current_buf_start;
|
|
|
unsigned long start_byte;
|
|
|
+ unsigned long prev_start_byte;
|
|
|
unsigned long working_bytes = total_out - buf_start;
|
|
|
unsigned long bytes;
|
|
|
char *kaddr;
|
|
@@ -1071,26 +1072,34 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
|
|
|
if (!bio->bi_iter.bi_size)
|
|
|
return 0;
|
|
|
bvec = bio_iter_iovec(bio, bio->bi_iter);
|
|
|
-
|
|
|
+ prev_start_byte = start_byte;
|
|
|
start_byte = page_offset(bvec.bv_page) - disk_start;
|
|
|
|
|
|
/*
|
|
|
- * make sure our new page is covered by this
|
|
|
- * working buffer
|
|
|
+ * We need to make sure we're only adjusting
|
|
|
+ * our offset into compression working buffer when
|
|
|
+ * we're switching pages. Otherwise we can incorrectly
|
|
|
+ * keep copying when we were actually done.
|
|
|
*/
|
|
|
- if (total_out <= start_byte)
|
|
|
- return 1;
|
|
|
+ if (start_byte != prev_start_byte) {
|
|
|
+ /*
|
|
|
+ * make sure our new page is covered by this
|
|
|
+ * working buffer
|
|
|
+ */
|
|
|
+ if (total_out <= start_byte)
|
|
|
+ return 1;
|
|
|
|
|
|
- /*
|
|
|
- * the next page in the biovec might not be adjacent
|
|
|
- * to the last page, but it might still be found
|
|
|
- * inside this working buffer. bump our offset pointer
|
|
|
- */
|
|
|
- if (total_out > start_byte &&
|
|
|
- current_buf_start < start_byte) {
|
|
|
- buf_offset = start_byte - buf_start;
|
|
|
- working_bytes = total_out - start_byte;
|
|
|
- current_buf_start = buf_start + buf_offset;
|
|
|
+ /*
|
|
|
+ * the next page in the biovec might not be adjacent
|
|
|
+ * to the last page, but it might still be found
|
|
|
+ * inside this working buffer. bump our offset pointer
|
|
|
+ */
|
|
|
+ if (total_out > start_byte &&
|
|
|
+ current_buf_start < start_byte) {
|
|
|
+ buf_offset = start_byte - buf_start;
|
|
|
+ working_bytes = total_out - start_byte;
|
|
|
+ current_buf_start = buf_start + buf_offset;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|