[RHEL7,COMMIT] mm: cleancache: fix corruption on missed inode invalidation

Submitted by Konstantin Khorenko on Nov. 8, 2018, 2:47 p.m.

Details

Message ID 201811081447.wA8El5b8003981@finist-ce7.sw.ru
State New
Series "mm: cleancache: fix corruption on missed inode invalidation"
Headers show

Commit Message

Konstantin Khorenko Nov. 8, 2018, 2:47 p.m.
The commit is pushed to "branch-rh7-3.10.0-862.20.2.vz7.73.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.20.2.vz7.73.2
------>
commit ec85fae0b5d885a7f8c22e7022cd41dde067164e
Author: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Date:   Thu Nov 8 17:47:05 2018 +0300

    mm: cleancache: fix corruption on missed inode invalidation
    
    If all pages are deleted from the mapping by memory reclaim and also
    moved to the cleancache:
    
    __delete_from_page_cache
      (no shadow case)
      cleancache_put_page
      page_cache_tree_delete
        mapping->nrpages--
        (nrpages becomes 0)
    
    We don't clean the cleancache for an inode after final file truncation
    (removal).
    
    truncate_inode_pages_final
      check (nrpages || nrexceptional) is false
        no truncate_inode_pages
          no cleancache_invalidate_inode(mapping)
    
    These way when reading the new file created with same inode we may get
    these trash leftover pages from cleancache and see wrong data instead of
    the contents of the new file.
    
    Fix it by always doing truncate_inode_pages which is already ready for
    nrpages == 0 && nrexceptional == 0 case and just invalidates inode.
    
    https://jira.sw.ru/browse/PSBM-89050
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    Reviewed-by: Vasily Averin <vvs@virtuozzo.com>
---
 mm/truncate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/mm/truncate.c b/mm/truncate.c
index faf97ee9ac8a..1488d7e435b0 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -529,9 +529,9 @@  void truncate_inode_pages_final(struct address_space *mapping)
 		 */
 		spin_lock_irq(&mapping->tree_lock);
 		spin_unlock_irq(&mapping->tree_lock);
-
-		truncate_inode_pages(mapping, 0);
 	}
+
+	truncate_inode_pages(mapping, 0);
 }
 EXPORT_SYMBOL(truncate_inode_pages_final);