示例#1
0
int ceph_pagelist_release(struct ceph_pagelist *pl)
{
	ceph_pagelist_unmap_tail(pl);
	while (!list_empty(&pl->head)) {
		struct page *page = list_first_entry(&pl->head, struct page,
						     lru);
		list_del(&page->lru);
		__free_page(page);
	}
	ceph_pagelist_free_reserve(pl);
	return 0;
}
示例#2
0
void ceph_pagelist_release(struct ceph_pagelist *pl)
{
	if (!refcount_dec_and_test(&pl->refcnt))
		return;
	ceph_pagelist_unmap_tail(pl);
	while (!list_empty(&pl->head)) {
		struct page *page = list_first_entry(&pl->head, struct page,
						     lru);
		list_del(&page->lru);
		__free_page(page);
	}
	ceph_pagelist_free_reserve(pl);
	kfree(pl);
}
示例#3
0
static int ceph_pagelist_addpage(struct ceph_pagelist *pl)
{
	struct page *page;

	if (!pl->num_pages_free) {
		page = __page_cache_alloc(GFP_NOFS);
	} else {
		page = list_first_entry(&pl->free_list, struct page, lru);
		list_del(&page->lru);
		--pl->num_pages_free;
	}
	if (!page)
		return -ENOMEM;
	pl->room += PAGE_SIZE;
	ceph_pagelist_unmap_tail(pl);
	list_add_tail(&page->lru, &pl->head);
	pl->mapped_tail = kmap(page);
	return 0;
}
示例#4
0
/**
 * Truncate a pagelist to the given point. Move extra pages to reserve.
 * This won't sleep.
 * Returns: 0 on success,
 *          -EINVAL if the pagelist doesn't match the trunc point pagelist
 */
int ceph_pagelist_truncate(struct ceph_pagelist *pl,
			   struct ceph_pagelist_cursor *c)
{
	struct page *page;

	if (pl != c->pl)
		return -EINVAL;
	ceph_pagelist_unmap_tail(pl);
	while (pl->head.prev != c->page_lru) {
		page = list_entry(pl->head.prev, struct page, lru);
		list_del(&page->lru);                /* remove from pagelist */
		list_add_tail(&page->lru, &pl->free_list); /* add to reserve */
		++pl->num_pages_free;
	}
	pl->room = c->room;
	if (!list_empty(&pl->head)) {
		page = list_entry(pl->head.prev, struct page, lru);
		pl->mapped_tail = kmap(page);
	}