From: Badari Pulavarty 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: Andrew Morton --- 25-akpm/fs/direct-io.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-) diff -puN fs/direct-io.c~dio-pages-in-io-accounting-fix fs/direct-io.c --- 25/fs/direct-io.c~dio-pages-in-io-accounting-fix 2004-08-16 11:51:25.669776408 -0700 +++ 25-akpm/fs/direct-io.c 2004-08-16 11:51:25.673775800 -0700 @@ -561,7 +561,11 @@ static int dio_bio_add_page(struct dio * ret = bio_add_page(dio->bio, dio->cur_page, dio->cur_page_len, dio->cur_page_offset); if (ret == dio->cur_page_len) { - dio->pages_in_io--; + /* + * 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--; page_cache_get(dio->cur_page); dio->final_block_in_bio = dio->cur_page_block + (dio->cur_page_len >> dio->blkbits); _