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/

Reply via email to