tmpfs: fix shmem_getpage_gfp VM_BUG_ON
Fuzzing with trinity hit the "impossible" VM_BUG_ON(error) (which Fedora
has converted to WARNING) in shmem_getpage_gfp():
WARNING: at mm/shmem.c:1151 shmem_getpage_gfp+0xa5c/0xa70()
Pid: 29795, comm: trinity-child4 Not tainted 3.7.0-rc2+ #49
Call Trace:
[<
ffffffff8107100f>] warn_slowpath_common+0x7f/0xc0
[<
ffffffff8107106a>] warn_slowpath_null+0x1a/0x20
[<
ffffffff811903fc>] shmem_getpage_gfp+0xa5c/0xa70
[<
ffffffff81190e4f>] shmem_fault+0x4f/0xa0
[<
ffffffff8119f391>] __do_fault+0x71/0x5c0
[<
ffffffff811a2767>] handle_pte_fault+0x97/0xae0
[<
ffffffff811a4a39>] handle_mm_fault+0x289/0x350
[<
ffffffff816d091e>] __do_page_fault+0x18e/0x530
[<
ffffffff816d0ceb>] do_page_fault+0x2b/0x50
[<
ffffffff816cd3b8>] page_fault+0x28/0x30
[<
ffffffff816d5688>] tracesys+0xe1/0xe6
Thanks to Johannes for pointing to truncation: free_swap_and_cache() only
does a trylock on the page, so the page lock we've held since before
confirming swap is not enough to protect against truncation.
What cleanup is needed in this case? Just delete_from_swap_cache(), which
takes care of the memcg uncharge.
Reported-by: Dave Jones <davej@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.com>
Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>