Skip to content

Commit

Permalink
[PATCH] fix blk_direct_IO bio preparation
Browse files Browse the repository at this point in the history
For large size DIO that needs multiple bio, one full page worth of data was
lost at the boundary of bio's maximum sector or segment limits.  After a
bio is full and got submitted.  The outer while (nbytes) { ...  } loop will
allocate a new bio and just march on to index into next page.  It just
forgets about the page that bio_add_page() rejected when previous bio is
full.  Fix it by put the rejected page back to pvec so we pick it up again
for the next bio.

Signed-off-by: Ken Chen <kenneth.w.chen@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Chen, Kenneth W authored and Linus Torvalds committed Jan 23, 2007
1 parent 15c945c commit cda9205
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
return pvec->page[pvec->idx++];
}

/* return a page back to pvec array */
static void blk_unget_page(struct page *page, struct pvec *pvec)
{
pvec->page[--pvec->idx] = page;
}

static ssize_t
blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
loff_t pos, unsigned long nr_segs)
Expand Down Expand Up @@ -278,6 +284,8 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
count = min(count, nbytes);
goto same_bio;
}
} else {
blk_unget_page(page, &pvec);
}

/* bio is ready, submit it */
Expand Down

0 comments on commit cda9205

Please sign in to comment.