From: Jens Axboe <axboe@suse.de>

Dog slow software suspend found this one. If WB_SYNC_ALL, then you need
to mark the bio as sync as well.

This is because swap_writepage() does a remove_exclusive_swap_page() (going
to __delete_from_swap_cache -> __remove_from_page_cache) which can kill
page->mapping, thus aops->sync_page() has nothing to work with for unplugging
the address space.


---

 25-akpm/mm/page_io.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff -puN mm/page_io.c~swap_writepage-BIO_RW_SYNC mm/page_io.c
--- 25/mm/page_io.c~swap_writepage-BIO_RW_SYNC	Mon Apr  5 14:17:45 2004
+++ 25-akpm/mm/page_io.c	Mon Apr  5 14:17:45 2004
@@ -90,7 +90,7 @@ static int end_swap_bio_read(struct bio 
 int swap_writepage(struct page *page, struct writeback_control *wbc)
 {
 	struct bio *bio;
-	int ret = 0;
+	int ret = 0, rw = WRITE;
 
 	if (remove_exclusive_swap_page(page)) {
 		unlock_page(page);
@@ -103,10 +103,12 @@ int swap_writepage(struct page *page, st
 		ret = -ENOMEM;
 		goto out;
 	}
+	if (wbc->sync_mode == WB_SYNC_ALL)
+		rw |= (1 << BIO_RW_SYNC);
 	inc_page_state(pswpout);
 	set_page_writeback(page);
 	unlock_page(page);
-	submit_bio(WRITE, bio);
+	submit_bio(rw, bio);
 out:
 	return ret;
 }

_