aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2011-05-11 15:13:37 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-21 15:13:11 -0700
commitfe27581573a4901c83b9c3dadf6f1f2221d9df50 (patch)
tree6996ed4fe4d60451cf3ae8430ebba09700ba8e10 /arch
parent52db907b9df439c6dbee0856e8bf48be62f81027 (diff)
tmpfs: fix race between umount and swapoff
commit 778dd893ae785c5fd505dac30b5fc40aae188bf1 upstream. The use of igrab() in swapoff's shmem_unuse_inode() is just as vulnerable to umount as that in shmem_writepage(). Fix this instance by extending the protection of shmem_swaplist_mutex right across shmem_unuse_inode(): while it's on the list, the inode cannot be evicted (and the filesystem cannot be unmounted) without shmem_evict_inode() taking that mutex to remove it from the list. But since shmem_writepage() might take that mutex, we should avoid making memory allocations or memcg charges while holding it: prepare them at the outer level in shmem_unuse(). When mem_cgroup_cache_charge() was originally placed, we didn't know until that point that the page from swap was actually a shmem page; but nowadays it's noted in the swap_map, so we're safe to charge upfront. For the radix_tree, do as is done in shmem_getpage(): preload upfront, but don't pin to the cpu; so we make a habit of refreshing the node pool, but might dip into GFP_NOWAIT reserves on occasion if subsequently preempted. With the allocation and charge moved out from shmem_unuse_inode(), we can also hold index map and info->lock over from finding the entry. 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>
Diffstat (limited to 'arch')
0 files changed, 0 insertions, 0 deletions