tmpfs: fix race between truncate and writepage
authorHugh Dickins <hughd@google.com>
Sat, 28 May 2011 20:14:09 +0000 (13:14 -0700)
committerSteve Conklin <sconklin@canonical.com>
Fri, 15 Jul 2011 17:21:10 +0000 (12:21 -0500)
commitdcbb952e55ec99a9d14b4f2ee3577ade1feebcd7
tree406a3ba615a33227a1cfc18f52765255c2ded940
parent845835e8681d3f1dcecec313adddb258598423f0
tmpfs: fix race between truncate and writepage

BugLink: http://bugs.launchpad.net/bugs/793702

commit 826267cf1e6c6899eda1325a19f1b1d15c558b20 upstream.

While running fsx on tmpfs with a memhog then swapoff, swapoff was hanging
(interruptibly), repeatedly failing to locate the owner of a 0xff entry in
the swap_map.

Although shmem_writepage() does abandon when it sees incoming page index
is beyond eof, there was still a window in which shmem_truncate_range()
could come in between writepage's dropping lock and updating swap_map,
find the half-completed swap_map entry, and in trying to free it,
leave it in a state that swap_shmem_alloc() could not correct.

Arguably a bug in __swap_duplicate()'s and swap_entry_free()'s handling
of the different cases, but easiest to fix by moving swap_shmem_alloc()
under cover of the lock.

More interesting than the bug: it's been there since 2.6.33, why could
I not see it with earlier kernels?  The mmotm of two weeks ago seems to
have some magic for generating races, this is just one of three I found.

With yesterday's git I first saw this in mainline, bisected in search of
that magic, but the easy reproducibility evaporated.  Oh well, fix the bug.

Signed-off-by: Hugh Dickins <hughd@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
mm/shmem.c