Exemplo n.º 1
0
/*
 * This is like invalidate_complete_page(), except it ignores the page's
 * refcount.  We do this because invalidate_inode_pages2() needs stronger
 * invalidation guarantees, and cannot afford to leave pages behind because
 * shrink_page_list() has a temp ref on them, or because they're transiently
 * sitting in the lru_cache_add() pagevecs.
 */
static int
invalidate_complete_page2(struct address_space *mapping, struct page *page)
{
    struct mem_cgroup *memcg;
    unsigned long flags;

    if (page->mapping != mapping)
        return 0;

    if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL))
        return 0;

    memcg = mem_cgroup_begin_page_stat(page);
    spin_lock_irqsave(&mapping->tree_lock, flags);
    if (PageDirty(page))
        goto failed;

    BUG_ON(page_has_private(page));
    __delete_from_page_cache(page, NULL, memcg);
    spin_unlock_irqrestore(&mapping->tree_lock, flags);
    mem_cgroup_end_page_stat(memcg);

    if (mapping->a_ops->freepage)
        mapping->a_ops->freepage(page);

    page_cache_release(page);	/* pagecache ref */
    return 1;
failed:
    spin_unlock_irqrestore(&mapping->tree_lock, flags);
    mem_cgroup_end_page_stat(memcg);
    return 0;
}
Exemplo n.º 2
0
/**
 * delete_from_page_cache - delete page from page cache
 * @page: the page which the kernel is trying to remove from page cache
 *
 * This must be called only on pages that have been verified to be in the page
 * cache and locked.  It will never put the page into the free list, the caller
 * has a reference on the page.
 */
void delete_from_page_cache(struct page *page)
{
	struct address_space *mapping = page->mapping;
	struct mem_cgroup *memcg;
	unsigned long flags;

	void (*freepage)(struct page *);

	BUG_ON(!PageLocked(page));

	freepage = mapping->a_ops->freepage;

	memcg = mem_cgroup_begin_page_stat(page);
	spin_lock_irqsave(&mapping->tree_lock, flags);
	__delete_from_page_cache(page, NULL, memcg);
	spin_unlock_irqrestore(&mapping->tree_lock, flags);
	mem_cgroup_end_page_stat(memcg);

	if (freepage)
		freepage(page);
	page_cache_release(page);
}