Commit 8ece6262 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] tag dirty pages as such in the radix tree

Arrange for all dirty pagecache pages to be tagged as dirty within their
radix tree.
parent 89261aab
......@@ -873,6 +873,8 @@ int __set_page_dirty_buffers(struct page *page)
inc_page_state(nr_dirty);
list_del(&page->list);
list_add(&page->list, &mapping->dirty_pages);
radix_tree_tag_set(&mapping->page_tree, page->index,
PAGECACHE_TAG_DIRTY);
}
spin_unlock_irq(&mapping->tree_lock);
__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
......
......@@ -364,6 +364,13 @@ struct block_device {
unsigned long bd_private;
};
/*
* Radix-tre tags, for tagging dirty and writeback pages within the pagecache
* radix trees
*/
#define PAGECACHE_TAG_DIRTY 0
#define PAGECACHE_TAG_WRITEBACK 1
/*
* Use sequence counter to get consistent i_size on 32-bit processors.
*/
......
......@@ -318,4 +318,6 @@ static inline void clear_page_dirty(struct page *page)
test_clear_page_dirty(page);
}
int __clear_page_dirty(struct page *page);
#endif /* PAGE_FLAGS_H */
......@@ -522,6 +522,8 @@ int __set_page_dirty_nobuffers(struct page *page)
inc_page_state(nr_dirty);
list_del(&page->list);
list_add(&page->list, &mapping->dirty_pages);
radix_tree_tag_set(&mapping->page_tree,
page->index, PAGECACHE_TAG_DIRTY);
}
spin_unlock_irq(&mapping->tree_lock);
if (!PageSwapCache(page))
......@@ -560,13 +562,45 @@ EXPORT_SYMBOL(set_page_dirty_lock);
*/
int test_clear_page_dirty(struct page *page)
{
if (TestClearPageDirty(page)) {
struct address_space *mapping = page->mapping;
unsigned long flags;
if (mapping && !mapping->backing_dev_info->memory_backed)
if (mapping) {
spin_lock_irqsave(&mapping->tree_lock, flags);
if (TestClearPageDirty(page)) {
radix_tree_tag_clear(&mapping->page_tree, page->index,
PAGECACHE_TAG_DIRTY);
spin_unlock_irqrestore(&mapping->tree_lock, flags);
if (!mapping->backing_dev_info->memory_backed)
dec_page_state(nr_dirty);
return 1;
}
spin_unlock_irqrestore(&mapping->tree_lock, flags);
return 0;
}
return TestClearPageDirty(page);
}
EXPORT_SYMBOL(test_clear_page_dirty);
/*
* Clear a page's dirty flag while ignoring dirty memory accounting
*/
int __clear_page_dirty(struct page *page)
{
struct address_space *mapping = page->mapping;
if (mapping) {
unsigned long flags;
spin_lock_irqsave(&mapping->tree_lock, flags);
if (TestClearPageDirty(page)) {
radix_tree_tag_clear(&mapping->page_tree, page->index,
PAGECACHE_TAG_DIRTY);
spin_unlock_irqrestore(&mapping->tree_lock, flags);
return 1;
}
spin_unlock_irqrestore(&mapping->tree_lock, flags);
return 0;
}
return TestClearPageDirty(page);
}
......@@ -149,7 +149,7 @@ int add_to_swap(struct page * page)
switch (err) {
case 0: /* Success */
SetPageUptodate(page);
ClearPageDirty(page);
__clear_page_dirty(page);
set_page_dirty(page);
INC_CACHE_INFO(add_total);
return 1;
......@@ -246,7 +246,7 @@ int move_from_swap_cache(struct page *page, unsigned long index,
if (!err) {
swap_free(entry);
/* shift page from clean_pages to dirty_pages list */
ClearPageDirty(page);
__clear_page_dirty(page);
set_page_dirty(page);
}
return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment