blob: 45f6eb29adf9fea84dc4c7a50bac66c895580fa1 [file] [log] [blame]
#include <linux/module.h>
#include "blkback-pagemap.h"
static int blkback_pagemap_size;
static struct blkback_pagemap *blkback_pagemap;
static inline int
blkback_pagemap_entry_clear(struct blkback_pagemap *map)
{
static struct blkback_pagemap zero;
return !memcmp(map, &zero, sizeof(zero));
}
int
blkback_pagemap_init(int pages)
{
blkback_pagemap = kzalloc(pages * sizeof(struct blkback_pagemap),
GFP_KERNEL);
if (!blkback_pagemap)
return -ENOMEM;
blkback_pagemap_size = pages;
return 0;
}
EXPORT_SYMBOL_GPL(blkback_pagemap_init);
void
blkback_pagemap_set(int idx, struct page *page,
domid_t domid, busid_t busid, grant_ref_t gref)
{
struct blkback_pagemap *entry;
BUG_ON(!blkback_pagemap);
BUG_ON(idx >= blkback_pagemap_size);
set_page_private(page, idx);
entry = blkback_pagemap + idx;
if (!blkback_pagemap_entry_clear(entry)) {
printk("overwriting pagemap %d: d %u b %u g %u\n",
idx, entry->domid, entry->busid, entry->gref);
BUG();
}
entry->page = page;
entry->domid = domid;
entry->busid = busid;
entry->gref = gref;
}
EXPORT_SYMBOL_GPL(blkback_pagemap_set);
void
blkback_pagemap_clear(struct page *page)
{
int idx;
struct blkback_pagemap *entry;
idx = (int)page_private(page);
BUG_ON(!blkback_pagemap);
BUG_ON(idx >= blkback_pagemap_size);
entry = blkback_pagemap + idx;
if (blkback_pagemap_entry_clear(entry)) {
printk("clearing empty pagemap %d\n", idx);
BUG();
}
memset(entry, 0, sizeof(*entry));
}
EXPORT_SYMBOL_GPL(blkback_pagemap_clear);
struct blkback_pagemap
blkback_pagemap_read(struct page *page)
{
int idx;
struct blkback_pagemap *entry;
idx = (int)page_private(page);
BUG_ON(!blkback_pagemap);
BUG_ON(idx >= blkback_pagemap_size);
entry = blkback_pagemap + idx;
if (blkback_pagemap_entry_clear(entry)) {
printk("reading empty pagemap %d\n", idx);
BUG();
}
return *entry;
}
EXPORT_SYMBOL(blkback_pagemap_read);
MODULE_LICENSE("Dual BSD/GPL");
int
blkback_pagemap_contains_page(struct page *page)
{
struct blkback_pagemap *entry;
int idx = (int)page_private(page);
if (idx < 0 || idx >= blkback_pagemap_size)
return 0;
entry = blkback_pagemap + idx;
return (entry->page == page);
}
EXPORT_SYMBOL(blkback_pagemap_contains_page);