tmpfs: fix spurious ENOSPC when racing with unswap
authorHugh Dickins <hughd@google.com>
Wed, 11 May 2011 22:13:38 +0000 (15:13 -0700)
committerSteve Conklin <sconklin@canonical.com>
Thu, 2 Jun 2011 19:23:27 +0000 (14:23 -0500)
commit67ec50dd894959d43b0370b5c84e4ac442590b37
tree5a085cbadb90ad07d70107341ea2ae765062c915
parent8becce8820aa6b766ff7a9ea168cccbead64fe21
tmpfs: fix spurious ENOSPC when racing with unswap

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

commit 59a16ead572330deb38e5848151d30ed1af754bc upstream.

Testing the shmem_swaplist replacements for igrab() revealed another bug:
writes to /dev/loop0 on a tmpfs file which fills its filesystem were
sometimes failing with "Buffer I/O error"s.

These came from ENOSPC failures of shmem_getpage(), when racing with
swapoff: the same could happen when racing with another shmem_getpage(),
pulling the page in from swap in between our find_lock_page() and our
taking the info->lock (though not in the single-threaded loop case).

This is unacceptable, and surprising that I've not noticed it before:
it dates back many years, but (presumably) was made a lot easier to
reproduce in 2.6.36, which sited a page preallocation in the race window.

Fix it by rechecking the page cache before settling on an ENOSPC error.

Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: Konstantin Khlebnikov <khlebnikov@openvz.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Steve Conklin <sconklin@canonical.com>
mm/shmem.c