summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2015-06-16 08:48:56 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-06-25 04:49:32 -0400
commitfdd4e15838e59c394a1ec4963b57c22c12608685 (patch)
treeb5486f7b0f12abf9ed670d187f4841dfdb2aa13e /fs/ceph/caps.c
parentb459be739f97e2062b2ba77cfe8ea198dbd58904 (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.c14
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)) {