summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-04-11 23:11:08 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-04-11 23:11:08 -0700
commit40c8348ec03fa2c525e13ca6ee54279735563ee4 (patch)
treec4c5f40d3c9ca4774322018a441248be89ded478
parent8ece6262c5fef1b935a944f5d16965ff7dd5d1cc (diff)
[PATCH] tag writeback pages as such in their radix tree
Arrange for under-writeback pages to be marked thus in their pagecache radix tree.
-rw-r--r--fs/buffer.c4
-rw-r--r--fs/mpage.c2
-rw-r--r--fs/nfs/write.c2
-rw-r--r--fs/ntfs/aops.c4
-rw-r--r--fs/reiserfs/inode.c4
-rw-r--r--fs/xfs/linux/xfs_aops.c2
-rw-r--r--include/linux/page-flags.h8
-rw-r--r--mm/filemap.c3
-rw-r--r--mm/page-writeback.c42
-rw-r--r--mm/page_io.c2
-rw-r--r--mm/swap.c2
11 files changed, 61 insertions, 14 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 59f4508a472f..56b0df6bf752 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1829,7 +1829,7 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
} 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);
/*
@@ -1892,7 +1892,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 --git a/fs/mpage.c b/fs/mpage.c
index c3e781cb4906..5f5f5e63fca2 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -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 --git a/fs/nfs/write.c b/fs/nfs/write.c
index 83bc0b498a01..53bff1a2a731 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -768,7 +768,7 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data, int how)
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_list_add_request(req, &data->pages);
- SetPageWriteback(req->wb_page);
+ set_page_writeback(req->wb_page);
*pages++ = req->wb_page;
count += req->wb_bytes;
}
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index e3b1c227cb7b..bb048a75318d 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -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 *page, struct writeback_control *wbc)
// 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 --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 31016572683e..c01847228d2c 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2134,7 +2134,7 @@ static int reiserfs_write_full_page(struct page *page, struct writeback_control
} 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 --git a/fs/xfs/linux/xfs_aops.c b/fs/xfs/linux/xfs_aops.c
index dd446266d33f..52a8c40d7f71 100644
--- a/fs/xfs/linux/xfs_aops.c
+++ b/fs/xfs/linux/xfs_aops.c
@@ -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);
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 9f4fb3da00d9..bd6ddb279c55 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -312,12 +312,18 @@ extern struct address_space swapper_space;
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 --git a/mm/filemap.c b/mm/filemap.c
index 360c5feec975..4d5e76ceaf29 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -363,8 +363,7 @@ void end_page_writeback(struct page *page)
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 --git a/mm/page-writeback.c b/mm/page-writeback.c
index 23da9ce262ca..bc4f3258daf2 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -604,3 +604,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 --git a/mm/page_io.c b/mm/page_io.c
index 421f77d2c39c..dde9d23f99bd 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -104,7 +104,7 @@ int swap_writepage(struct page *page, struct writeback_control *wbc)
goto out;
}
inc_page_state(pswpout);
- SetPageWriteback(page);
+ set_page_writeback(page);
unlock_page(page);
submit_bio(WRITE, bio);
out:
diff --git a/mm/swap.c b/mm/swap.c
index a5352c98751a..90a9ac490a3c 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -70,7 +70,7 @@ int rotate_reclaimable_page(struct page *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;