aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2010-02-09 14:14:41 -0500
committerSage Weil <sage@newdream.net>2010-02-11 14:48:51 -0500
commit29065a513aa4c7e4b46b77cbcd25f814a4ca0bfe (patch)
tree74607baf067fe47a5eeeeb07257186fdd15de989 /fs/ceph
parent3d497d858ae6e5f23a28783030aecc69074e102d (diff)
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 <yehuda@hq.newdream.net> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/file.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 43bd2f2e51a5..bbf1ccf2d56e 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)
409 i++; 409 i++;
410 } 410 }
411 while (len >= PAGE_CACHE_SIZE) { 411 while (len >= PAGE_CACHE_SIZE) {
412 dout("zeroing %d %p\n", i, pages[i]); 412 dout("zeroing %d %p len=%d\n", i, pages[i], len);
413 zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); 413 zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
414 len -= PAGE_CACHE_SIZE; 414 len -= PAGE_CACHE_SIZE;
415 i++; 415 i++;
@@ -542,13 +542,16 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data,
542 * but it will at least behave sensibly when they are 542 * but it will at least behave sensibly when they are
543 * in sequence. 543 * in sequence.
544 */ 544 */
545 filemap_write_and_wait(inode->i_mapping);
546 } else { 545 } else {
547 pages = alloc_page_vector(num_pages); 546 pages = alloc_page_vector(num_pages);
548 } 547 }
549 if (IS_ERR(pages)) 548 if (IS_ERR(pages))
550 return PTR_ERR(pages); 549 return PTR_ERR(pages);
551 550
551 ret = filemap_write_and_wait(inode->i_mapping);
552 if (ret < 0)
553 goto done;
554
552 ret = striped_read(inode, off, len, pages, num_pages); 555 ret = striped_read(inode, off, len, pages, num_pages);
553 556
554 if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) 557 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,
556 if (ret >= 0) 559 if (ret >= 0)
557 *poff = off + ret; 560 *poff = off + ret;
558 561
562done:
559 if (file->f_flags & O_DIRECT) 563 if (file->f_flags & O_DIRECT)
560 put_page_vector(pages, num_pages); 564 put_page_vector(pages, num_pages);
561 else 565 else
@@ -617,6 +621,16 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data,
617 else 621 else
618 pos = *offset; 622 pos = *offset;
619 623
624 ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left);
625 if (ret < 0)
626 return ret;
627
628 ret = invalidate_inode_pages2_range(inode->i_mapping,
629 pos >> PAGE_CACHE_SHIFT,
630 (pos + left) >> PAGE_CACHE_SHIFT);
631 if (ret < 0)
632 dout("invalidate_inode_pages2_range returned %d\n", ret);
633
620 flags = CEPH_OSD_FLAG_ORDERSNAP | 634 flags = CEPH_OSD_FLAG_ORDERSNAP |
621 CEPH_OSD_FLAG_ONDISK | 635 CEPH_OSD_FLAG_ONDISK |
622 CEPH_OSD_FLAG_WRITE; 636 CEPH_OSD_FLAG_WRITE;