Пример #1
0
/*
 * "Store" data from a page to frontswap and associate it with the page's
 * swaptype and offset.  Page must be locked and in the swap cache.
 * If frontswap already contains a page with matching swaptype and
 * offset, the frontswap implementation may either overwrite the data and
 * return success or invalidate the page from frontswap and return failure.
 */
int __frontswap_store(struct page *page)
{
	int ret = -1, dup = 0;
	swp_entry_t entry = { .val = page_private(page), };
	int type = swp_type(entry);
	struct swap_info_struct *sis = swap_info[type];
	pgoff_t offset = swp_offset(entry);

	BUG_ON(!PageLocked(page));
	BUG_ON(sis == NULL);
	if (frontswap_test(sis, offset))
		dup = 1;
	ret = frontswap_ops.store(type, offset, page);
	if (ret == 0) {
		frontswap_set(sis, offset);
		inc_frontswap_succ_stores();
		if (!dup)
			atomic_inc(&sis->frontswap_pages);
	} else {
		/*
		  failed dup always results in automatic invalidate of
		  the (older) page from frontswap
		 */
		inc_frontswap_failed_stores();
		if (dup)
			__frontswap_clear(sis, offset);
	}
	if (frontswap_writethrough_enabled)
		/* report failure so swap also writes to swap device */
		ret = -1;
	return ret;
}
Пример #2
0
/*
* "Put" data from a page to frontswap and associate it with the page's
* swaptype and offset. Page must be locked and in the swap cache.
* If frontswap already contains a page with matching swaptype and
* offset, the frontswap implmentation may either overwrite the data
* and return success or flush the page from frontswap and return failure
*/
int __frontswap_put_page(struct page *page)
{
int ret = -1, dup = 0;
swp_entry_t entry = { .val = page_private(page), };
int type = swp_type(entry);
struct swap_info_struct *sis = swap_info[type];
pgoff_t offset = swp_offset(entry);

BUG_ON(!PageLocked(page));
if (frontswap_test(sis, offset))
dup = 1;
ret = (*frontswap_ops.put_page)(type, offset, page);
if (ret == 0) {
frontswap_set(sis, offset);
frontswap_succ_puts++;
if (!dup)
sis->frontswap_pages++;
} else if (dup) {
/*
failed dup always results in automatic flush of
the (older) page from frontswap
*/
frontswap_clear(sis, offset);
sis->frontswap_pages--;
frontswap_failed_puts++;
} else
frontswap_failed_puts++;
return ret;
}
Пример #3
0
/*
 * Invalidate any data from frontswap associated with the specified swaptype
 * and offset so that a subsequent "get" will fail.
 */
void __frontswap_invalidate_page(unsigned type, pgoff_t offset)
{
	struct swap_info_struct *sis = swap_info[type];

	BUG_ON(sis == NULL);
	if (frontswap_test(sis, offset)) {
		frontswap_ops.invalidate_page(type, offset);
		__frontswap_clear(sis, offset);
		inc_frontswap_invalidates();
	}
}
Пример #4
0
/*
* Flush any data from frontswap associated with the specified swaptype
* and offset so that a subsequent "get" will fail.
*/
void __frontswap_flush_page(unsigned type, pgoff_t offset)
{
struct swap_info_struct *sis = swap_info[type];

if (frontswap_test(sis, offset)) {
(*frontswap_ops.flush_page)(type, offset);
sis->frontswap_pages--;
frontswap_clear(sis, offset);
frontswap_flushes++;
}
}
Пример #5
0
/*
* "Get" data from frontswap associated with swaptype and offset that were
* specified when the data was put to frontswap and use it to fill the
* specified page with data. Page must be locked and in the swap cache
*/
int __frontswap_get_page(struct page *page)
{
int ret = -1;
swp_entry_t entry = { .val = page_private(page), };
int type = swp_type(entry);
struct swap_info_struct *sis = swap_info[type];
pgoff_t offset = swp_offset(entry);

BUG_ON(!PageLocked(page));
if (frontswap_test(sis, offset))
ret = (*frontswap_ops.get_page)(type, offset, page);
if (ret == 0)
frontswap_gets++;
return ret;
}
Пример #6
0
/*
 * "Get" data from frontswap associated with swaptype and offset that were
 * specified when the data was put to frontswap and use it to fill the
 * specified page with data. Page must be locked and in the swap cache.
 */
int __frontswap_load(struct page *page)
{
	int ret = -1;
	swp_entry_t entry = { .val = page_private(page), };
	int type = swp_type(entry);
	struct swap_info_struct *sis = swap_info[type];
	pgoff_t offset = swp_offset(entry);

	BUG_ON(!PageLocked(page));
	BUG_ON(sis == NULL);
	if (frontswap_test(sis, offset))
		ret = frontswap_ops.load(type, offset, page);
	if (ret == 0) {
		inc_frontswap_loads();
		if (frontswap_tmem_exclusive_gets_enabled) {
			SetPageDirty(page);
			frontswap_clear(sis, offset);
		}
	}
	return ret;
}