aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-05-27 13:40:43 -0400
committerSage Weil <sage@newdream.net>2010-08-01 23:11:39 -0400
commit2962507ca204f886967e1a089d9bec206d427c22 (patch)
treee9cec16b13ad1d8e41c288658e62fb3bf1c66859
parent33caad324b88f75f42d836735d86feaafb3b40cf (diff)
ceph: perform lazy reads when file mode and caps permit
If the file mode is marked as "lazy," perform cached/buffered reads when the caps permit it. Adjust the rdcache_gen and invalidation logic accordingly so that we manage our cache based on the FILE_CACHE -or- FILE_LAZYIO cap bits. Signed-off-by: Sage Weil <sage@newdream.net>
-rw-r--r--fs/ceph/addr.c2
-rw-r--r--fs/ceph/caps.c16
-rw-r--r--fs/ceph/file.c12
-rw-r--r--fs/ceph/inode.c5
4 files changed, 22 insertions, 13 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index d9c60b84949a..e00797eed29c 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -552,7 +552,7 @@ static void writepages_finish(struct ceph_osd_request *req,
552 * page truncation thread, possibly losing some data that 552 * page truncation thread, possibly losing some data that
553 * raced its way in 553 * raced its way in
554 */ 554 */
555 if ((issued & CEPH_CAP_FILE_CACHE) == 0) 555 if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0)
556 generic_error_remove_page(inode->i_mapping, page); 556 generic_error_remove_page(inode->i_mapping, page);
557 557
558 unlock_page(page); 558 unlock_page(page);
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 1a70a3ebf013..b28915d5f404 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -482,8 +482,8 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
482 * Each time we receive FILE_CACHE anew, we increment 482 * Each time we receive FILE_CACHE anew, we increment
483 * i_rdcache_gen. 483 * i_rdcache_gen.
484 */ 484 */
485 if ((issued & CEPH_CAP_FILE_CACHE) && 485 if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
486 (had & CEPH_CAP_FILE_CACHE) == 0) 486 (had & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0)
487 ci->i_rdcache_gen++; 487 ci->i_rdcache_gen++;
488 488
489 /* 489 /*
@@ -1509,11 +1509,13 @@ retry_locked:
1509 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ 1509 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */
1510 ci->i_rdcache_gen && /* may have cached pages */ 1510 ci->i_rdcache_gen && /* may have cached pages */
1511 (file_wanted == 0 || /* no open files */ 1511 (file_wanted == 0 || /* no open files */
1512 (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */ 1512 (revoking & (CEPH_CAP_FILE_CACHE|
1513 CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */
1513 !tried_invalidate) { 1514 !tried_invalidate) {
1514 dout("check_caps trying to invalidate on %p\n", inode); 1515 dout("check_caps trying to invalidate on %p\n", inode);
1515 if (try_nonblocking_invalidate(inode) < 0) { 1516 if (try_nonblocking_invalidate(inode) < 0) {
1516 if (revoking & CEPH_CAP_FILE_CACHE) { 1517 if (revoking & (CEPH_CAP_FILE_CACHE|
1518 CEPH_CAP_FILE_LAZYIO)) {
1517 dout("check_caps queuing invalidate\n"); 1519 dout("check_caps queuing invalidate\n");
1518 queue_invalidate = 1; 1520 queue_invalidate = 1;
1519 ci->i_rdcache_revoking = ci->i_rdcache_gen; 1521 ci->i_rdcache_revoking = ci->i_rdcache_gen;
@@ -2276,7 +2278,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2276 * try to invalidate (once). (If there are dirty buffers, we 2278 * try to invalidate (once). (If there are dirty buffers, we
2277 * will invalidate _after_ writeback.) 2279 * will invalidate _after_ writeback.)
2278 */ 2280 */
2279 if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && 2281 if (((cap->issued & ~newcaps) & (CEPH_CAP_FILE_CACHE|
2282 CEPH_CAP_FILE_LAZYIO)) &&
2280 !ci->i_wrbuffer_ref) { 2283 !ci->i_wrbuffer_ref) {
2281 if (try_nonblocking_invalidate(inode) == 0) { 2284 if (try_nonblocking_invalidate(inode) == 0) {
2282 revoked_rdcache = 1; 2285 revoked_rdcache = 1;
@@ -2374,7 +2377,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
2374 writeback = 1; /* will delay ack */ 2377 writeback = 1; /* will delay ack */
2375 else if (dirty & ~newcaps) 2378 else if (dirty & ~newcaps)
2376 check_caps = 1; /* initiate writeback in check_caps */ 2379 check_caps = 1; /* initiate writeback in check_caps */
2377 else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 || 2380 else if (((used & ~newcaps) & (CEPH_CAP_FILE_CACHE|
2381 CEPH_CAP_FILE_LAZYIO)) == 0 ||
2378 revoked_rdcache) 2382 revoked_rdcache)
2379 check_caps = 2; /* send revoke ack in check_caps */ 2383 check_caps = 2; /* send revoke ack in check_caps */
2380 cap->issued = newcaps; 2384 cap->issued = newcaps;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 85c86ed5f4c0..2329244f427b 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -740,28 +740,32 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
740 unsigned long nr_segs, loff_t pos) 740 unsigned long nr_segs, loff_t pos)
741{ 741{
742 struct file *filp = iocb->ki_filp; 742 struct file *filp = iocb->ki_filp;
743 struct ceph_file_info *fi = filp->private_data;
743 loff_t *ppos = &iocb->ki_pos; 744 loff_t *ppos = &iocb->ki_pos;
744 size_t len = iov->iov_len; 745 size_t len = iov->iov_len;
745 struct inode *inode = filp->f_dentry->d_inode; 746 struct inode *inode = filp->f_dentry->d_inode;
746 struct ceph_inode_info *ci = ceph_inode(inode); 747 struct ceph_inode_info *ci = ceph_inode(inode);
747 void *base = iov->iov_base; 748 void *base = iov->iov_base;
748 ssize_t ret; 749 ssize_t ret;
749 int got = 0; 750 int want, got = 0;
750 int checkeof = 0, read = 0; 751 int checkeof = 0, read = 0;
751 752
752 dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n", 753 dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
753 inode, ceph_vinop(inode), pos, (unsigned)len, inode); 754 inode, ceph_vinop(inode), pos, (unsigned)len, inode);
754again: 755again:
755 __ceph_do_pending_vmtruncate(inode); 756 __ceph_do_pending_vmtruncate(inode);
756 ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE, 757 if (fi->fmode & CEPH_FILE_MODE_LAZY)
757 &got, -1); 758 want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
759 else
760 want = CEPH_CAP_FILE_CACHE;
761 ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, &got, -1);
758 if (ret < 0) 762 if (ret < 0)
759 goto out; 763 goto out;
760 dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n", 764 dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
761 inode, ceph_vinop(inode), pos, (unsigned)len, 765 inode, ceph_vinop(inode), pos, (unsigned)len,
762 ceph_cap_string(got)); 766 ceph_cap_string(got));
763 767
764 if ((got & CEPH_CAP_FILE_CACHE) == 0 || 768 if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
765 (iocb->ki_filp->f_flags & O_DIRECT) || 769 (iocb->ki_filp->f_flags & O_DIRECT) ||
766 (inode->i_sb->s_flags & MS_SYNCHRONOUS)) 770 (inode->i_sb->s_flags & MS_SYNCHRONOUS))
767 /* hmm, this isn't really async... */ 771 /* hmm, this isn't really async... */
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 389f9dbd9949..5d893d31e399 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -442,8 +442,9 @@ int ceph_fill_file_size(struct inode *inode, int issued,
442 * the file is either opened or mmaped 442 * the file is either opened or mmaped
443 */ 443 */
444 if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD| 444 if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD|
445 CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER| 445 CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER|
446 CEPH_CAP_FILE_EXCL)) || 446 CEPH_CAP_FILE_EXCL|
447 CEPH_CAP_FILE_LAZYIO)) ||
447 mapping_mapped(inode->i_mapping) || 448 mapping_mapped(inode->i_mapping) ||
448 __ceph_caps_file_wanted(ci)) { 449 __ceph_caps_file_wanted(ci)) {
449 ci->i_truncate_pending++; 450 ci->i_truncate_pending++;