| From 6ff38bd40230af35e446239396e5fc8ebd6a5248 Mon Sep 17 00:00:00 2001 |
| From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> |
| Date: Fri, 30 Nov 2018 14:09:00 -0800 |
| Subject: mm: cleancache: fix corruption on missed inode invalidation |
| |
| From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> |
| |
| commit 6ff38bd40230af35e446239396e5fc8ebd6a5248 upstream. |
| |
| If all pages are deleted from the mapping by memory reclaim and also |
| moved to the cleancache: |
| |
| __delete_from_page_cache |
| (no shadow case) |
| unaccount_page_cache_page |
| cleancache_put_page |
| page_cache_delete |
| mapping->nrpages -= nr |
| (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. |
| |
| [akpm@linux-foundation.org: add comment, per Jan] |
| Link: http://lkml.kernel.org/r/20181112095734.17979-1-ptikhomirov@virtuozzo.com |
| Fixes: commit 91b0abe36a7b ("mm + fs: store shadow entries in page cache") |
| Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> |
| Reviewed-by: Vasily Averin <vvs@virtuozzo.com> |
| Reviewed-by: Andrey Ryabinin <aryabinin@virtuozzo.com> |
| Reviewed-by: Jan Kara <jack@suse.cz> |
| Cc: Johannes Weiner <hannes@cmpxchg.org> |
| Cc: Mel Gorman <mgorman@techsingularity.net> |
| Cc: Matthew Wilcox <willy@infradead.org> |
| Cc: Andi Kleen <ak@linux.intel.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Vasily Averin <vvs@virtuozzo.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| mm/truncate.c | 8 ++++++-- |
| 1 file changed, 6 insertions(+), 2 deletions(-) |
| |
| --- a/mm/truncate.c |
| +++ b/mm/truncate.c |
| @@ -457,9 +457,13 @@ void truncate_inode_pages_final(struct a |
| */ |
| spin_lock_irq(&mapping->tree_lock); |
| spin_unlock_irq(&mapping->tree_lock); |
| - |
| - truncate_inode_pages(mapping, 0); |
| } |
| + |
| + /* |
| + * Cleancache needs notification even if there are no pages or shadow |
| + * entries. |
| + */ |
| + truncate_inode_pages(mapping, 0); |
| } |
| EXPORT_SYMBOL(truncate_inode_pages_final); |
| |