Commit 17ccf8a6 authored by Badari Pulavarty's avatar Badari Pulavarty Committed by Linus Torvalds

[PATCH] DIO pages-in-io accounting fix

I found one more accounting inconsistency with dio_pages_in_io.  This is a
day-one bug and I started hitting it on latest -mm due to the recent
changes to dio_pages_in_io calculations to be exact.

If the file is badly fragmented (no contiguous blocks at all), and the user
buffer is not page aligned - we need to create IO for each disk block with
2 pages.  (bio with 2 vecs).

dio_bio_add_page() should not decrement dio_pages_in_io for every add page.
 It should only decrement, it only if its done with that page and moving on
to next page.  (since dio_pages_in_io represent how many actual pages we
are operating on).

Here is the patch to fix this accounting.  Without this patch, we will hit
BUG() in dio_new_bio() with O_DIRECT on filesystems.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a89555fb
...@@ -561,6 +561,10 @@ static int dio_bio_add_page(struct dio *dio) ...@@ -561,6 +561,10 @@ static int dio_bio_add_page(struct dio *dio)
ret = bio_add_page(dio->bio, dio->cur_page, ret = bio_add_page(dio->bio, dio->cur_page,
dio->cur_page_len, dio->cur_page_offset); dio->cur_page_len, dio->cur_page_offset);
if (ret == dio->cur_page_len) { if (ret == dio->cur_page_len) {
/*
* Decrement count only, if we are done with this page
*/
if ((dio->cur_page_len + dio->cur_page_offset) == PAGE_SIZE)
dio->pages_in_io--; dio->pages_in_io--;
page_cache_get(dio->cur_page); page_cache_get(dio->cur_page);
dio->final_block_in_bio = dio->cur_page_block + dio->final_block_in_bio = dio->cur_page_block +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment