

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/fs/nfs/write.c             |    4 +--
 25-akpm/fs/ntfs/aops.c             |    4 +--
 25-akpm/fs/reiserfs/inode.c        |    4 +--
 25-akpm/fs/xfs/linux/xfs_aops.c    |    2 -
 25-akpm/include/linux/page-flags.h |    8 ++++++-
 25-akpm/mm/filemap.c               |    3 --
 25-akpm/mm/page-writeback.c        |   42 +++++++++++++++++++++++++++++++++++++
 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 
 18 files changed, 62 insertions(+), 15 deletions(-)

diff -puN fs/buffer.c~tag-writeback-pages fs/buffer.c
--- 25/fs/buffer.c~tag-writeback-pages	2004-03-19 10:35:41.716830712 -0800
+++ 25-akpm/fs/buffer.c	2004-03-19 10:35:41.744826456 -0800
@@ -1837,7 +1837,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);
 
 	/*
@@ -1900,7 +1900,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	2004-03-19 10:35:41.718830408 -0800
+++ 25-akpm/fs/mpage.c	2004-03-19 10:35:41.744826456 -0800
@@ -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	2004-03-19 10:35:41.719830256 -0800
+++ 25-akpm/mm/filemap.c	2004-03-19 10:35:41.746826152 -0800
@@ -365,8 +365,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	2004-03-19 10:35:41.721829952 -0800
+++ 25-akpm/mm/page_io.c	2004-03-19 10:35:41.746826152 -0800
@@ -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	2004-03-19 10:35:41.723829648 -0800
+++ 25-akpm/mm/swap.c	2004-03-19 10:35:41.747826000 -0800
@@ -70,7 +70,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	2004-03-19 10:35:41.733828128 -0800
+++ 25-akpm/include/linux/page-flags.h	2004-03-19 10:35:41.747826000 -0800
@@ -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	2004-03-19 10:35:41.734827976 -0800
+++ 25-akpm/mm/page-writeback.c	2004-03-19 10:35:41.748825848 -0800
@@ -652,3 +652,45 @@ 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;
+
+}
+EXPORT_SYMBOL(test_set_page_writeback);
diff -puN fs/nfs/write.c~tag-writeback-pages fs/nfs/write.c
--- 25/fs/nfs/write.c~tag-writeback-pages	2004-03-19 10:35:41.736827672 -0800
+++ 25-akpm/fs/nfs/write.c	2004-03-19 10:35:41.749825696 -0800
@@ -924,7 +924,7 @@ static int nfs_flush_multi(struct list_h
 	atomic_set(&req->wb_complete, requests);
 
 	ClearPageError(page);
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	offset = 0;
 	nbytes = req->wb_bytes;
 	do {
@@ -987,7 +987,7 @@ static int nfs_flush_one(struct list_hea
 		nfs_list_remove_request(req);
 		nfs_list_add_request(req, &data->pages);
 		ClearPageError(req->wb_page);
-		SetPageWriteback(req->wb_page);
+		set_page_writeback(req->wb_page);
 		*pages++ = req->wb_page;
 		count += req->wb_bytes;
 	}
diff -puN fs/ntfs/aops.c~tag-writeback-pages fs/ntfs/aops.c
--- 25/fs/ntfs/aops.c~tag-writeback-pages	2004-03-19 10:35:41.737827520 -0800
+++ 25-akpm/fs/ntfs/aops.c	2004-03-19 10:35:41.751825392 -0800
@@ -743,7 +743,7 @@ lock_retry_remap:
 	}
 
 	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);
 
 	/*
@@ -885,7 +885,7 @@ static int ntfs_writepage(struct page *p
 	// FIXME: Make sure it is ok to SetPageError() on unlocked page under
 	// writeback before doing the change!
 #if 0
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	unlock_page(page);
 #endif
 
diff -puN fs/reiserfs/inode.c~tag-writeback-pages fs/reiserfs/inode.c
--- 25/fs/reiserfs/inode.c~tag-writeback-pages	2004-03-19 10:35:41.739827216 -0800
+++ 25-akpm/fs/reiserfs/inode.c	2004-03-19 10:35:41.753825088 -0800
@@ -2134,7 +2134,7 @@ static int reiserfs_write_full_page(stru
     } while(bh != head) ;
 
     BUG_ON(PageWriteback(page));
-    SetPageWriteback(page);
+    set_page_writeback(page);
     unlock_page(page);
 
     /*
@@ -2198,7 +2198,7 @@ fail:
     } while(bh != 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/xfs/linux/xfs_aops.c~tag-writeback-pages fs/xfs/linux/xfs_aops.c
--- 25/fs/xfs/linux/xfs_aops.c~tag-writeback-pages	2004-03-19 10:35:41.740827064 -0800
+++ 25-akpm/fs/xfs/linux/xfs_aops.c	2004-03-19 10:35:41.754824936 -0800
@@ -566,7 +566,7 @@ xfs_submit_page(
 	int			i;
 
 	BUG_ON(PageWriteback(page));
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	clear_page_dirty(page);
 	unlock_page(page);
 

_
