diff options
author | Sage Weil <sage@newdream.net> | 2010-05-27 13:40:43 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-08-01 23:11:39 -0400 |
commit | 2962507ca204f886967e1a089d9bec206d427c22 (patch) | |
tree | e9cec16b13ad1d8e41c288658e62fb3bf1c66859 | |
parent | 33caad324b88f75f42d836735d86feaafb3b40cf (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.c | 2 | ||||
-rw-r--r-- | fs/ceph/caps.c | 16 | ||||
-rw-r--r-- | fs/ceph/file.c | 12 | ||||
-rw-r--r-- | fs/ceph/inode.c | 5 |
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); |
754 | again: | 755 | again: |
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++; |