diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-04-11 23:11:08 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-04-11 23:11:08 -0700 |
| commit | 40c8348ec03fa2c525e13ca6ee54279735563ee4 (patch) | |
| tree | c4c5f40d3c9ca4774322018a441248be89ded478 | |
| parent | 8ece6262c5fef1b935a944f5d16965ff7dd5d1cc (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.c | 4 | ||||
| -rw-r--r-- | fs/mpage.c | 2 | ||||
| -rw-r--r-- | fs/nfs/write.c | 2 | ||||
| -rw-r--r-- | fs/ntfs/aops.c | 4 | ||||
| -rw-r--r-- | fs/reiserfs/inode.c | 4 | ||||
| -rw-r--r-- | fs/xfs/linux/xfs_aops.c | 2 | ||||
| -rw-r--r-- | include/linux/page-flags.h | 8 | ||||
| -rw-r--r-- | mm/filemap.c | 3 | ||||
| -rw-r--r-- | mm/page-writeback.c | 42 | ||||
| -rw-r--r-- | mm/page_io.c | 2 | ||||
| -rw-r--r-- | mm/swap.c | 2 |
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; |
