--- /dev/null
+From hughd@google.com Wed Aug 11 16:03:09 2010
+Date: Wed, 11 Aug 2010 15:32:15 -0700 (PDT)
+From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+cc: gregkh@suse.de, kamezawa.hiroyu@jp.fujitsu.com, akpm@linux-foundation.org,
+ andrea.gelmini@gmail.com, linux@rainbow-software.org, rjw@sisk.pl,
+ torvalds@linux-foundation.org, stable@kernel.org,
+ stable-commits@vger.kernel.org
+Subject: mm: fix corruption of hibernation caused by reusing swap during image saving
+Message-ID: <alpine.DEB.1.00.1008111522070.13309@tigran.mtv.corp.google.com>
+
+From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+
+commit 966cca029f739716fbcc8068b8c6dfe381f86fc3 upstream.
+
+Since 2.6.31, swap_map[]'s refcounting was changed to show that a used
+swap entry is just for swap-cache, can be reused. Then, while scanning
+free entry in swap_map[], a swap entry may be able to be reclaimed and
+reused. It was caused by commit c9e444103b5e7a5 ("mm: reuse unused swap
+entry if necessary").
+
+But this caused deta corruption at resume. The scenario is
+
+- Assume a clean-swap cache, but mapped.
+
+- at hibernation_snapshot[], clean-swap-cache is saved as
+ clean-swap-cache and swap_map[] is marked as SWAP_HAS_CACHE.
+
+- then, save_image() is called. And reuse SWAP_HAS_CACHE entry to save
+ image, and break the contents.
+
+After resume:
+
+- the memory reclaim runs and finds clean-not-referenced-swap-cache and
+ discards it because it's marked as clean. But here, the contents on
+ disk and swap-cache is inconsistent.
+
+Hance memory is corrupted.
+
+This patch avoids the bug by not reclaiming swap-entry during hibernation.
+This is a quick fix for backporting.
+
+Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Reported-by: Ondreg Zary <linux@rainbow-software.org>
+Tested-by: Ondreg Zary <linux@rainbow-software.org>
+Tested-by: Andrea Gelmini <andrea.gelmini@gmail.com>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+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>
+
+
+---
+ mm/swapfile.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -330,8 +330,10 @@ checks:
+ if (offset > si->highest_bit)
+ scan_base = offset = si->lowest_bit;
+
+- /* reuse swap entry of cache-only swap if not busy. */
+- if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
++ /* reuse swap entry of cache-only swap if not hibernation. */
++ if (vm_swap_full()
++ && cache == SWAP_CACHE
++ && si->swap_map[offset] == SWAP_HAS_CACHE) {
+ int swap_was_freed;
+ spin_unlock(&swap_lock);
+ swap_was_freed = __try_to_reclaim_swap(si, offset);