int test_clear_page_writeback(struct page *page) { struct address_space *mapping = page_mapping(page); int ret; if (mapping) { struct backing_dev_info *bdi = mapping->backing_dev_info; unsigned long flags; spin_lock_irqsave(&mapping->tree_lock, flags); ret = TestClearPageWriteback(page); if (ret) { radix_tree_tag_clear(&mapping->page_tree, page_index(page), PAGECACHE_TAG_WRITEBACK); if (bdi_cap_account_writeback(bdi)) { __dec_bdi_stat(bdi, BDI_WRITEBACK); __bdi_writeout_inc(bdi); } } spin_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestClearPageWriteback(page); } if (ret) dec_zone_page_state(page, NR_WRITEBACK); return ret; }
/* * Writeback is about to end against a page which has been marked for immediate * reclaim. If it still appears to be reclaimable, move it to the tail of the * inactive list. The page still has PageWriteback set, which will pin it. * * We don't expect many pages to come through here, so don't bother batching * things up. * * To avoid placing the page at the tail of the LRU while PG_writeback is still * set, this function will clear PG_writeback before performing the page * motion. Do that inside the lru lock because once PG_writeback is cleared * we may not touch the page. * * Returns zero if it cleared PG_writeback. */ int rotate_reclaimable_page(struct page *page) { struct zone *zone; unsigned long flags; if (PageLocked(page)) return 1; if (PageDirty(page)) return 1; if (PageActive(page)) return 1; if (!PageLRU(page)) return 1; zone = page_zone(page); spin_lock_irqsave(&zone->lru_lock, flags); if (PageLRU(page) && !PageActive(page)) { list_del(&page->lru); list_add_tail(&page->lru, &zone->inactive_list); inc_page_state(pgrotated); } if (!TestClearPageWriteback(page)) BUG(); spin_unlock_irqrestore(&zone->lru_lock, flags); return 0; }
int test_clear_page_writeback(struct page *page) { struct address_space *mapping = page_mapping(page); int ret; if (mapping) { unsigned long flags; write_lock_irqsave(&mapping->tree_lock, flags); ret = TestClearPageWriteback(page); if (ret) radix_tree_tag_clear(&mapping->page_tree, page_index(page), PAGECACHE_TAG_WRITEBACK); write_unlock_irqrestore(&mapping->tree_lock, flags); } else { ret = TestClearPageWriteback(page); } return ret; }