ceph: don't invalidate page cache when inode is no longer used
authorYan, Zheng <zyan@redhat.com>
Mon, 26 Oct 2015 08:08:43 +0000 (16:08 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 2 Nov 2015 22:36:48 +0000 (23:36 +0100)
ceph_check_caps() invalidate page cache when inode is not used
by any open file. This behaviour is not friendly for workload
that repeatly read files.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/caps.c
fs/ceph/mds_client.c

index 27b5668..3493153 100644 (file)
@@ -1655,9 +1655,8 @@ retry_locked:
            !S_ISDIR(inode->i_mode) &&          /* ignore readdir cache */
            ci->i_wrbuffer_ref == 0 &&          /* no dirty pages... */
            inode->i_data.nrpages &&            /* have cached pages */
-           (file_wanted == 0 ||                /* no open files */
-            (revoking & (CEPH_CAP_FILE_CACHE|
-                         CEPH_CAP_FILE_LAZYIO))) && /*  or revoking cache */
+           (revoking & (CEPH_CAP_FILE_CACHE|
+                        CEPH_CAP_FILE_LAZYIO)) && /*  or revoking cache */
            !tried_invalidate) {
                dout("check_caps trying to invalidate on %p\n", inode);
                if (try_nonblocking_invalidate(inode) < 0) {
index fe2c982..a7a967a 100644 (file)
@@ -1430,6 +1430,13 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
                if ((used | wanted) & CEPH_CAP_ANY_WR)
                        goto out;
        }
+       /* The inode has cached pages, but it's no longer used.
+        * we can safely drop it */
+       if (wanted == 0 && used == CEPH_CAP_FILE_CACHE &&
+           !(oissued & CEPH_CAP_FILE_CACHE)) {
+         used = 0;
+         oissued = 0;
+       }
        if ((used | wanted) & ~oissued & mine)
                goto out;   /* we need these caps */
 
@@ -1438,7 +1445,7 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
                /* we aren't the only cap.. just remove us */
                __ceph_remove_cap(cap, true);
        } else {
-               /* try to drop referring dentries */
+               /* try dropping referring dentries */
                spin_unlock(&ci->i_ceph_lock);
                d_prune_aliases(inode);
                dout("trim_caps_cb %p cap %p  pruned, count now %d\n",