

Arrange for under-writeback pages to be marked thus in their pagecache radix
tree.


---

 25-akpm/fs/buffer.c                |    4 +--
 25-akpm/fs/mpage.c                 |    2 -
 25-akpm/include/linux/page-flags.h |    8 ++++++-
 25-akpm/mm/filemap.c               |    3 --
 25-akpm/mm/page-writeback.c        |   41 +++++++++++++++++++++++++++++++++++++
 25-akpm/mm/page_io.c               |    2 -
 25-akpm/mm/swap.c                  |    2 -
 include/linux/fs.h                 |    0 
 include/linux/mm.h                 |    0 
 mm/shmem.c                         |    0 
 mm/swap_state.c                    |    0 
 mm/swapfile.c                      |    0 
 mm/truncate.c                      |    0 
 mm/vmscan.c                        |    0 
 14 files changed, 54 insertions(+), 8 deletions(-)

diff -puN fs/buffer.c~tag-writeback-pages fs/buffer.c
--- 25/fs/buffer.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/fs/buffer.c	Wed Mar 10 15:47:18 2004
@@ -1834,7 +1834,7 @@ static int __block_write_full_page(struc
 	} while ((bh = bh->b_this_page) != head);
 
 	BUG_ON(PageWriteback(page));
-	SetPageWriteback(page);		/* Keeps try_to_free_buffers() away */
+	set_page_writeback(page);	/* Keeps try_to_free_buffers() away */
 	unlock_page(page);
 
 	/*
@@ -1897,7 +1897,7 @@ recover:
 	} while ((bh = bh->b_this_page) != head);
 	SetPageError(page);
 	BUG_ON(PageWriteback(page));
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	unlock_page(page);
 	do {
 		struct buffer_head *next = bh->b_this_page;
diff -puN fs/mpage.c~tag-writeback-pages fs/mpage.c
--- 25/fs/mpage.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/fs/mpage.c	Wed Mar 10 15:47:18 2004
@@ -546,7 +546,7 @@ alloc_new:
 	}
 
 	BUG_ON(PageWriteback(page));
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	unlock_page(page);
 	if (boundary || (first_unmapped != blocks_per_page)) {
 		bio = mpage_bio_submit(WRITE, bio);
diff -puN mm/filemap.c~tag-writeback-pages mm/filemap.c
--- 25/mm/filemap.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/mm/filemap.c	Wed Mar 10 15:47:18 2004
@@ -363,8 +363,7 @@ void end_page_writeback(struct page *pag
 	wait_queue_head_t *waitqueue = page_waitqueue(page);
 
 	if (!TestClearPageReclaim(page) || rotate_reclaimable_page(page)) {
-		smp_mb__before_clear_bit();
-		if (!TestClearPageWriteback(page))
+		if (!test_clear_page_writeback(page))
 			BUG();
 		smp_mb__after_clear_bit();
 	}
diff -puN mm/page_io.c~tag-writeback-pages mm/page_io.c
--- 25/mm/page_io.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/mm/page_io.c	Wed Mar 10 15:47:18 2004
@@ -104,7 +104,7 @@ int swap_writepage(struct page *page, st
 		goto out;
 	}
 	inc_page_state(pswpout);
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	unlock_page(page);
 	submit_bio(WRITE, bio);
 out:
diff -puN mm/shmem.c~tag-writeback-pages mm/shmem.c
diff -puN mm/swap.c~tag-writeback-pages mm/swap.c
--- 25/mm/swap.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/mm/swap.c	Wed Mar 10 15:47:18 2004
@@ -67,7 +67,7 @@ int rotate_reclaimable_page(struct page 
 		list_add_tail(&page->lru, &zone->inactive_list);
 		inc_page_state(pgrotated);
 	}
-	if (!TestClearPageWriteback(page))
+	if (!test_clear_page_writeback(page))
 		BUG();
 	spin_unlock_irqrestore(&zone->lru_lock, flags);
 	return 0;
diff -puN mm/swapfile.c~tag-writeback-pages mm/swapfile.c
diff -puN mm/swap_state.c~tag-writeback-pages mm/swap_state.c
diff -puN mm/truncate.c~tag-writeback-pages mm/truncate.c
diff -puN mm/vmscan.c~tag-writeback-pages mm/vmscan.c
diff -puN include/linux/fs.h~tag-writeback-pages include/linux/fs.h
diff -puN include/linux/mm.h~tag-writeback-pages include/linux/mm.h
diff -puN include/linux/page-flags.h~tag-writeback-pages include/linux/page-flags.h
--- 25/include/linux/page-flags.h~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/include/linux/page-flags.h	Wed Mar 10 15:47:18 2004
@@ -312,12 +312,18 @@ extern struct address_space swapper_spac
 struct page;	/* forward declaration */
 
 int test_clear_page_dirty(struct page *page);
+int __clear_page_dirty(struct page *page);
+int test_clear_page_writeback(struct page *page);
+int test_set_page_writeback(struct page *page);
 
 static inline void clear_page_dirty(struct page *page)
 {
 	test_clear_page_dirty(page);
 }
 
-int __clear_page_dirty(struct page *page);
+static inline void set_page_writeback(struct page *page)
+{
+	test_set_page_writeback(page);
+}
 
 #endif	/* PAGE_FLAGS_H */
diff -puN mm/page-writeback.c~tag-writeback-pages mm/page-writeback.c
--- 25/mm/page-writeback.c~tag-writeback-pages	Wed Mar 10 15:47:18 2004
+++ 25-akpm/mm/page-writeback.c	Wed Mar 10 15:47:18 2004
@@ -650,3 +650,44 @@ int __clear_page_dirty(struct page *page
 	}
 	return TestClearPageDirty(page);
 }
+
+int test_clear_page_writeback(struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	int ret;
+
+	if (mapping) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&mapping->tree_lock, flags);
+		ret = TestClearPageWriteback(page);
+		if (ret)
+			radix_tree_tag_clear(&mapping->page_tree, page->index,
+						PAGECACHE_TAG_WRITEBACK);
+		spin_unlock_irqrestore(&mapping->tree_lock, flags);
+	} else {
+		ret = TestClearPageWriteback(page);
+	}
+	return ret;
+}
+
+int test_set_page_writeback(struct page *page)
+{
+	struct address_space *mapping = page->mapping;
+	int ret;
+
+	if (mapping) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&mapping->tree_lock, flags);
+		ret = TestSetPageWriteback(page);
+		if (ret)
+			radix_tree_tag_set(&mapping->page_tree, page->index,
+						PAGECACHE_TAG_WRITEBACK);
+		spin_unlock_irqrestore(&mapping->tree_lock, flags);
+	} else {
+		ret = TestSetPageWriteback(page);
+	}
+	return ret;
+
+}

_
