diff options
author | Yan, Zheng <zyan@redhat.com> | 2015-06-16 08:48:56 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2015-06-25 04:49:32 -0400 |
commit | fdd4e15838e59c394a1ec4963b57c22c12608685 (patch) | |
tree | b5486f7b0f12abf9ed670d187f4841dfdb2aa13e /fs/ceph/caps.c | |
parent | b459be739f97e2062b2ba77cfe8ea198dbd58904 (diff) |
ceph: rework dcache readdir
Previously our dcache readdir code relies on that child dentries in
directory dentry's d_subdir list are sorted by dentry's offset in
descending order. When adding dentries to the dcache, if a dentry
already exists, our readdir code moves it to head of directory
dentry's d_subdir list. This design relies on dcache internals.
Al Viro suggests using ncpfs's approach: keeping array of pointers
to dentries in page cache of directory inode. the validity of those
pointers are presented by directory inode's complete and ordered
flags. When a dentry gets pruned, we clear directory inode's complete
flag in the d_prune() callback. Before moving a dentry to other
directory, we clear the ordered flag for both old and new directory.
Signed-off-by: Yan, Zheng <zyan@redhat.com>
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index dd7b20adf1d4..dc10c9dd36c1 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -833,7 +833,9 @@ int __ceph_caps_used(struct ceph_inode_info *ci) | |||
833 | used |= CEPH_CAP_PIN; | 833 | used |= CEPH_CAP_PIN; |
834 | if (ci->i_rd_ref) | 834 | if (ci->i_rd_ref) |
835 | used |= CEPH_CAP_FILE_RD; | 835 | used |= CEPH_CAP_FILE_RD; |
836 | if (ci->i_rdcache_ref || ci->vfs_inode.i_data.nrpages) | 836 | if (ci->i_rdcache_ref || |
837 | (!S_ISDIR(ci->vfs_inode.i_mode) && /* ignore readdir cache */ | ||
838 | ci->vfs_inode.i_data.nrpages)) | ||
837 | used |= CEPH_CAP_FILE_CACHE; | 839 | used |= CEPH_CAP_FILE_CACHE; |
838 | if (ci->i_wr_ref) | 840 | if (ci->i_wr_ref) |
839 | used |= CEPH_CAP_FILE_WR; | 841 | used |= CEPH_CAP_FILE_WR; |
@@ -1651,9 +1653,10 @@ retry_locked: | |||
1651 | * If we fail, it's because pages are locked.... try again later. | 1653 | * If we fail, it's because pages are locked.... try again later. |
1652 | */ | 1654 | */ |
1653 | if ((!is_delayed || mdsc->stopping) && | 1655 | if ((!is_delayed || mdsc->stopping) && |
1654 | ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ | 1656 | !S_ISDIR(inode->i_mode) && /* ignore readdir cache */ |
1655 | inode->i_data.nrpages && /* have cached pages */ | 1657 | ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ |
1656 | (file_wanted == 0 || /* no open files */ | 1658 | inode->i_data.nrpages && /* have cached pages */ |
1659 | (file_wanted == 0 || /* no open files */ | ||
1657 | (revoking & (CEPH_CAP_FILE_CACHE| | 1660 | (revoking & (CEPH_CAP_FILE_CACHE| |
1658 | CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */ | 1661 | CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */ |
1659 | !tried_invalidate) { | 1662 | !tried_invalidate) { |
@@ -2805,7 +2808,8 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc, | |||
2805 | * try to invalidate (once). (If there are dirty buffers, we | 2808 | * try to invalidate (once). (If there are dirty buffers, we |
2806 | * will invalidate _after_ writeback.) | 2809 | * will invalidate _after_ writeback.) |
2807 | */ | 2810 | */ |
2808 | if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && | 2811 | if (!S_ISDIR(inode->i_mode) && /* don't invalidate readdir cache */ |
2812 | ((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) && | ||
2809 | (newcaps & CEPH_CAP_FILE_LAZYIO) == 0 && | 2813 | (newcaps & CEPH_CAP_FILE_LAZYIO) == 0 && |
2810 | !ci->i_wrbuffer_ref) { | 2814 | !ci->i_wrbuffer_ref) { |
2811 | if (try_nonblocking_invalidate(inode)) { | 2815 | if (try_nonblocking_invalidate(inode)) { |