From 29065a513aa4c7e4b46b77cbcd25f814a4ca0bfe Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 9 Feb 2010 11:14:41 -0800 Subject: ceph: sync read/write considers page cache In the cases where we either do a sync read or a write, we need to make sure that everything in the page cache is flushed. In the case of a sync write we invalidate the relevant pages, so that subsequent read/write reflects the new data written. Signed-off-by: Yehuda Sadeh Signed-off-by: Sage Weil --- fs/ceph/file.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'fs/ceph/file.c') diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 43bd2f2e51a..bbf1ccf2d56 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -409,7 +409,7 @@ static void zero_page_vector_range(int off, int len, struct page **pages) i++; } while (len >= PAGE_CACHE_SIZE) { - dout("zeroing %d %p\n", i, pages[i]); + dout("zeroing %d %p len=%d\n", i, pages[i], len); zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); len -= PAGE_CACHE_SIZE; i++; @@ -542,13 +542,16 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, * but it will at least behave sensibly when they are * in sequence. */ - filemap_write_and_wait(inode->i_mapping); } else { pages = alloc_page_vector(num_pages); } if (IS_ERR(pages)) return PTR_ERR(pages); + ret = filemap_write_and_wait(inode->i_mapping); + if (ret < 0) + goto done; + ret = striped_read(inode, off, len, pages, num_pages); if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) @@ -556,6 +559,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, if (ret >= 0) *poff = off + ret; +done: if (file->f_flags & O_DIRECT) put_page_vector(pages, num_pages); else @@ -617,6 +621,16 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, else pos = *offset; + ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); + if (ret < 0) + return ret; + + ret = invalidate_inode_pages2_range(inode->i_mapping, + pos >> PAGE_CACHE_SHIFT, + (pos + left) >> PAGE_CACHE_SHIFT); + if (ret < 0) + dout("invalidate_inode_pages2_range returned %d\n", ret); + flags = CEPH_OSD_FLAG_ORDERSNAP | CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_WRITE; -- cgit v1.2.3-70-g09d2