ceph: don't use truncate_pagecache() to invalidate read cache
authorYan, Zheng <zyan@redhat.com>
Wed, 18 May 2016 12:58:26 +0000 (20:58 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 25 May 2016 23:15:42 +0000 (01:15 +0200)
truncate_pagecache() drops dirty pages, it's dangerous to use it
to invalidate read cache. Besides, we shouldn't start invalidating
read cache while there are buffer writers. Because buffer writers
may add dirty pages later.

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

index fab93c66d879f58fcad15d5b29c698f06873f7be..c17b5d76d75ee96515717ce29cc62971f80acca4 100644 (file)
@@ -1656,7 +1656,7 @@ retry_locked:
         */
        if ((!is_delayed || mdsc->stopping) &&
            !S_ISDIR(inode->i_mode) &&          /* ignore readdir cache */
-           ci->i_wrbuffer_ref == 0 &&          /* no dirty pages... */
+           !(ci->i_wb_ref || ci->i_wrbuffer_ref) &&   /* no dirty pages... */
            inode->i_data.nrpages &&            /* have cached pages */
            (revoking & (CEPH_CAP_FILE_CACHE|
                         CEPH_CAP_FILE_LAZYIO)) && /*  or revoking cache */
@@ -1698,8 +1698,8 @@ retry_locked:
 
                revoking = cap->implemented & ~cap->issued;
                dout(" mds%d cap %p used %s issued %s implemented %s revoking %s\n",
-                    cap->mds, cap, ceph_cap_string(cap->issued),
-                    ceph_cap_string(cap_used),
+                    cap->mds, cap, ceph_cap_string(cap_used),
+                    ceph_cap_string(cap->issued),
                     ceph_cap_string(cap->implemented),
                     ceph_cap_string(revoking));
 
@@ -2828,7 +2828,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
        if (!S_ISDIR(inode->i_mode) && /* don't invalidate readdir cache */
            ((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
            (newcaps & CEPH_CAP_FILE_LAZYIO) == 0 &&
-           !ci->i_wrbuffer_ref) {
+           !(ci->i_wrbuffer_ref || ci->i_wb_ref)) {
                if (try_nonblocking_invalidate(inode)) {
                        /* there were locked pages.. invalidate later
                           in a separate thread. */
index 89d08155986dfc43c96d1fa81f48ccb7af0c0e3c..07495ba61fe3ddbe2fcfd200f59cf3949907cd16 100644 (file)
@@ -1728,7 +1728,9 @@ static void ceph_invalidate_work(struct work_struct *work)
        orig_gen = ci->i_rdcache_gen;
        spin_unlock(&ci->i_ceph_lock);
 
-       truncate_pagecache(inode, 0);
+       if (invalidate_inode_pages2(inode->i_mapping) < 0) {
+               pr_err("invalidate_pages %p fails\n", inode);
+       }
 
        spin_lock(&ci->i_ceph_lock);
        if (orig_gen == ci->i_rdcache_gen &&