aboutsummaryrefslogtreecommitdiffstats
path: root/fs/direct-io.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-04-29 18:06:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-04-29 18:54:29 -0400
commitb1058b981272f5027f9be17241441198dbd1fefd (patch)
tree6e5bcb8d66347b7d7978c4a37f54304a0e9f18b9 /fs/direct-io.c
parent092c8d46e348b5fa4109a06d8a1246060e09dc8c (diff)
direct-io: submit bio after boundary buffer is added to it
Currently, dio_send_cur_page() submits bio before current page and cached sdio->cur_page is added to the bio if sdio->boundary is set. This is actually wrong because sdio->boundary means the current buffer is the last one before metadata needs to be read. So we should rather submit the bio after the current page is added to it. Signed-off-by: Jan Kara <jack@suse.cz> Reported-by: Kazuya Mio <k-mio@sx.jp.nec.com> Tested-by: Kazuya Mio <k-mio@sx.jp.nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/direct-io.c')
-rw-r--r--fs/direct-io.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 9644d0205dad..cfb816dc6d9f 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -672,12 +672,6 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio,
672 if (sdio->final_block_in_bio != sdio->cur_page_block || 672 if (sdio->final_block_in_bio != sdio->cur_page_block ||
673 cur_offset != bio_next_offset) 673 cur_offset != bio_next_offset)
674 dio_bio_submit(dio, sdio); 674 dio_bio_submit(dio, sdio);
675 /*
676 * Submit now if the underlying fs is about to perform a
677 * metadata read
678 */
679 else if (sdio->boundary)
680 dio_bio_submit(dio, sdio);
681 } 675 }
682 676
683 if (sdio->bio == NULL) { 677 if (sdio->bio == NULL) {
@@ -737,16 +731,6 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page,
737 sdio->cur_page_block + 731 sdio->cur_page_block +
738 (sdio->cur_page_len >> sdio->blkbits) == blocknr) { 732 (sdio->cur_page_len >> sdio->blkbits) == blocknr) {
739 sdio->cur_page_len += len; 733 sdio->cur_page_len += len;
740
741 /*
742 * If sdio->boundary then we want to schedule the IO now to
743 * avoid metadata seeks.
744 */
745 if (sdio->boundary) {
746 ret = dio_send_cur_page(dio, sdio, map_bh);
747 page_cache_release(sdio->cur_page);
748 sdio->cur_page = NULL;
749 }
750 goto out; 734 goto out;
751 } 735 }
752 736
@@ -758,7 +742,7 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page,
758 page_cache_release(sdio->cur_page); 742 page_cache_release(sdio->cur_page);
759 sdio->cur_page = NULL; 743 sdio->cur_page = NULL;
760 if (ret) 744 if (ret)
761 goto out; 745 return ret;
762 } 746 }
763 747
764 page_cache_get(page); /* It is in dio */ 748 page_cache_get(page); /* It is in dio */
@@ -768,6 +752,16 @@ submit_page_section(struct dio *dio, struct dio_submit *sdio, struct page *page,
768 sdio->cur_page_block = blocknr; 752 sdio->cur_page_block = blocknr;
769 sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits; 753 sdio->cur_page_fs_offset = sdio->block_in_file << sdio->blkbits;
770out: 754out:
755 /*
756 * If sdio->boundary then we want to schedule the IO now to
757 * avoid metadata seeks.
758 */
759 if (sdio->boundary) {
760 ret = dio_send_cur_page(dio, sdio, map_bh);
761 dio_bio_submit(dio, sdio);
762 page_cache_release(sdio->cur_page);
763 sdio->cur_page = NULL;
764 }
771 return ret; 765 return ret;
772} 766}
773 767