diff options
author | Jan Kara <jack@suse.cz> | 2013-04-29 18:06:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 18:54:29 -0400 |
commit | b1058b981272f5027f9be17241441198dbd1fefd (patch) | |
tree | 6e5bcb8d66347b7d7978c4a37f54304a0e9f18b9 /fs/direct-io.c | |
parent | 092c8d46e348b5fa4109a06d8a1246060e09dc8c (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.c | 28 |
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; |
770 | out: | 754 | out: |
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 | ||