public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] swap writepages swizzled
@ 2002-11-11 19:02 Hugh Dickins
  2002-11-11 19:14 ` Andrew Morton
  0 siblings, 1 reply; 2+ messages in thread
From: Hugh Dickins @ 2002-11-11 19:02 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

tmpfs failed fsx+swapout tests after many hours, a page found zeroed.
Not a truncate problem, but mirror image of earlier truncate problems:
swap goes through mpage_writepages, which must therefore allow for a
sudden swizzle back to file identity.

Second time this caught us, so I've audited the tree for other places
which might be surprised by such swizzling.  The only others I found
were (perhaps) in the parisc and sparc64 flush_dcache_page called
from do_generic_mapping_read on a looped tmpfs file which is also
mmapped; but that's a very marginal case, I wanted to understand it
better before making any edit, and now realize that hch's sendfile
in loop eliminates it (now go through do_shmem_file_read instead:
similar but crucially this locks the page when raising its count,
which is enough to keep vmscan from interfering).

Patch applies to 2.5.47, or 2.5.47-mm1 with offsets and fuzz.
Only the patch to mpage.c is required: I think it's worth adding
BUG_ON checks in __set_page_dirty_nobuffers and get_swap_bio,
just leave those out if you disagree; similarly, optional patch
to try_to_free_buffers, once upon a time swap came that way,
happily ever after it doesn't, so the test seems misleading.

Hugh

--- 2.5.47/fs/mpage.c	Mon Nov 11 08:26:55 2002
+++ linux/fs/mpage.c	Mon Nov 11 17:01:27 2002
@@ -587,12 +587,19 @@
 		page_cache_get(page);
 		write_unlock(&mapping->page_lock);
 
+		/*
+		 * At this point we hold neither mapping->page_lock nor
+		 * lock on the page itself: the page may be truncated or
+		 * invalidated (changing page->mapping to NULL), or even
+		 * swizzled back from swapper_space to tmpfs file mapping.
+		 */
+
 		lock_page(page);
 
 		if (sync)
 			wait_on_page_writeback(page);
 
-		if (page->mapping && !PageWriteback(page) &&
+		if (page->mapping == mapping && !PageWriteback(page) &&
 					test_clear_page_dirty(page)) {
 			if (writepage) {
 				ret = (*writepage)(page);
--- 2.5.47/mm/page-writeback.c	Thu Oct 31 05:40:06 2002
+++ linux/mm/page-writeback.c	Mon Nov 11 17:01:27 2002
@@ -613,6 +613,7 @@
 		if (mapping) {
 			write_lock(&mapping->page_lock);
 			if (page->mapping) {	/* Race with truncate? */
+				BUG_ON(page->mapping != mapping);
 				if (!mapping->backing_dev_info->memory_backed)
 					inc_page_state(nr_dirty);
 				list_del(&page->list);
--- 2.5.47/mm/page_io.c	Mon Oct  7 20:37:50 2002
+++ linux/mm/page_io.c	Mon Nov 11 17:01:27 2002
@@ -30,6 +30,7 @@
 		struct swap_info_struct *sis;
 		swp_entry_t entry;
 
+		BUG_ON(!PageSwapCache(page));
 		entry.val = page->index;
 		sis = get_swap_info_struct(swp_type(entry));
 
--- 2.5.47/fs/buffer.c	Mon Nov 11 08:26:55 2002
+++ linux/fs/buffer.c	Mon Nov 11 17:01:27 2002
@@ -2496,7 +2496,7 @@
 
 	spin_lock(&mapping->private_lock);
 	ret = drop_buffers(page, &buffers_to_free);
-	if (ret && !PageSwapCache(page)) {
+	if (ret) {
 		/*
 		 * If the filesystem writes its buffers by hand (eg ext3)
 		 * then we can have clean buffers against a dirty page.  We


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-11-11 19:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-11 19:02 [PATCH] swap writepages swizzled Hugh Dickins
2002-11-11 19:14 ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox