diff options
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r-- | fs/direct-io.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c index 5949947b060a..da111aacb46e 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -632,10 +632,26 @@ static int dio_send_cur_page(struct dio *dio) | |||
632 | int ret = 0; | 632 | int ret = 0; |
633 | 633 | ||
634 | if (dio->bio) { | 634 | if (dio->bio) { |
635 | loff_t cur_offset = dio->block_in_file << dio->blkbits; | ||
636 | loff_t bio_next_offset = dio->logical_offset_in_bio + | ||
637 | dio->bio->bi_size; | ||
638 | |||
635 | /* | 639 | /* |
636 | * See whether this new request is contiguous with the old | 640 | * See whether this new request is contiguous with the old. |
641 | * | ||
642 | * Btrfs cannot handl having logically non-contiguous requests | ||
643 | * submitted. For exmple if you have | ||
644 | * | ||
645 | * Logical: [0-4095][HOLE][8192-12287] | ||
646 | * Phyiscal: [0-4095] [4096-8181] | ||
647 | * | ||
648 | * We cannot submit those pages together as one BIO. So if our | ||
649 | * current logical offset in the file does not equal what would | ||
650 | * be the next logical offset in the bio, submit the bio we | ||
651 | * have. | ||
637 | */ | 652 | */ |
638 | if (dio->final_block_in_bio != dio->cur_page_block) | 653 | if (dio->final_block_in_bio != dio->cur_page_block || |
654 | cur_offset != bio_next_offset) | ||
639 | dio_bio_submit(dio); | 655 | dio_bio_submit(dio); |
640 | /* | 656 | /* |
641 | * Submit now if the underlying fs is about to perform a | 657 | * Submit now if the underlying fs is about to perform a |