Commit daf70db8 authored by Zach Brown's avatar Zach Brown Committed by Linus Torvalds

[PATCH] write and wait on range before direct io read

This adds filemap_write_and_wait_range(mapping, lstart, lend) which starts
writeback and waits on a range of pages.  We call this from
__blkdev_direct_IO with just the range that is going to be read by the
direct_IO read.  It was lightly tested with fsx and ext3 and passed.
Signed-off-by: default avatarZach Brown <zach.brown@oracle.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7afadfdc
......@@ -1206,7 +1206,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
*/
dio->lock_type = dio_lock_type;
if (dio_lock_type != DIO_NO_LOCKING) {
if (rw == READ) {
/* watch out for a 0 len io from a tricksy fs */
if (rw == READ && end > offset) {
struct address_space *mapping;
mapping = iocb->ki_filp->f_mapping;
......@@ -1214,7 +1215,9 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
down(&inode->i_sem);
reader_with_isem = 1;
}
retval = filemap_write_and_wait(mapping);
retval = filemap_write_and_wait_range(mapping, offset,
end - 1);
if (retval) {
kfree(dio);
goto out;
......
......@@ -1360,6 +1360,8 @@ extern int filemap_fdatawrite(struct address_space *);
extern int filemap_flush(struct address_space *);
extern int filemap_fdatawait(struct address_space *);
extern int filemap_write_and_wait(struct address_space *mapping);
extern int filemap_write_and_wait_range(struct address_space *mapping,
loff_t lstart, loff_t lend);
extern void sync_supers(void);
extern void sync_filesystems(int wait);
extern void emergency_sync(void);
......
......@@ -336,6 +336,22 @@ int filemap_write_and_wait(struct address_space *mapping)
return retval;
}
int filemap_write_and_wait_range(struct address_space *mapping,
loff_t lstart, loff_t lend)
{
int retval = 0;
if (mapping->nrpages) {
retval = __filemap_fdatawrite_range(mapping, lstart, lend,
WB_SYNC_ALL);
if (retval == 0)
retval = wait_on_page_writeback_range(mapping,
lstart >> PAGE_CACHE_SHIFT,
lend >> PAGE_CACHE_SHIFT);
}
return retval;
}
/*
* This function is used to add newly allocated pagecache pages:
* the page is new, so we can just run SetPageLocked() against it.
......
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