]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: make O_DIRECT io flush or truncate page cache pages
authorSage Weil <sage@newdream.net>
Sat, 14 Mar 2009 05:35:40 +0000 (22:35 -0700)
committerSage Weil <sage@newdream.net>
Sat, 14 Mar 2009 05:35:40 +0000 (22:35 -0700)
This will make concurrent O_DIRECT and normal i/o slow as all hell, but it
means that normal i/o followed by O_DIRECT (or the other way around) will
behave as expected.

src/kernel/file.c

index f4c3eeede339ba72c8542b79a83d2d4b97c3a01c..88548d88fd10e2e56756388bb436e90a7fd41f1e 100644 (file)
@@ -338,12 +338,22 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
        int read = 0;
        int ret;
 
-       dout(10, "sync_read on file %p %llu~%u\n", file, start_off, left);
+       dout(10, "sync_read on file %p %llu~%u %s\n", file, start_off, left,
+            (file->f_flags & O_DIRECT) ? "O_DIRECT":"");
 
-       if (file->f_flags & O_DIRECT)
+       if (file->f_flags & O_DIRECT) {
                pages = get_direct_page_vector(data, num_pages, pos, left);
-       else
+
+               /*
+                * flush any page cache pages in this range.  this
+                * will make concurrent normal and O_DIRECT io slow,
+                * but it will at least behave sensibly when they are
+                * in sequence.
+                */
+               filemap_write_and_wait_range(inode->i_mapping, pos, pos+left);
+       } else {
                pages = alloc_page_vector(num_pages);
+       }
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
@@ -421,6 +431,12 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
                pages = get_direct_page_vector(data, num_pages, pos, left);
                if (IS_ERR(pages))
                        return PTR_ERR(pages);
+
+               /*
+                * throw out any page cache pages in this range. this
+                * may block.
+                */
+               truncate_inode_pages_range(inode->i_mapping, pos, pos+left);
        } else {
                pages = alloc_page_vector(num_pages);
                if (IS_ERR(pages))