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 <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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);