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: Zach Brown <[EMAIL PROTECTED]> --- fs/direct-io.c | 7 +++++-- include/linux/fs.h | 2 ++ mm/filemap.c | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) Index: 2.6-bk-odirinv/fs/direct-io.c =================================================================== --- 2.6-bk-odirinv.orig/fs/direct-io.c 2005-02-07 11:19:40.000000000 -0800 +++ 2.6-bk-odirinv/fs/direct-io.c 2005-02-07 12:43:09.572259133 -0800 @@ -1206,7 +1206,8 @@ */ 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 @@ 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; Index: 2.6-bk-odirinv/include/linux/fs.h =================================================================== --- 2.6-bk-odirinv.orig/include/linux/fs.h 2005-02-07 11:26:23.000000000 -0800 +++ 2.6-bk-odirinv/include/linux/fs.h 2005-02-07 12:26:43.030749241 -0800 @@ -1359,6 +1359,8 @@ 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); Index: 2.6-bk-odirinv/mm/filemap.c =================================================================== --- 2.6-bk-odirinv.orig/mm/filemap.c 2005-02-07 11:26:23.000000000 -0800 +++ 2.6-bk-odirinv/mm/filemap.c 2005-02-07 13:00:29.723440763 -0800 @@ -336,6 +336,22 @@ 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. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/