--- /dev/null
+#include "common.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;
+}
+
+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);
+
+ SetPageBlkback(page);
+ 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->domid = domid;
+ entry->busid = busid;
+ entry->gref = gref;
+}
+
+void
+blkback_pagemap_clear(struct page *page)
+{
+ int idx;
+ struct blkback_pagemap *entry;
+
+ idx = (int)page_private(page);
+
+ BUG_ON(!blkback_pagemap);
+ BUG_ON(!PageBlkback(page));
+ 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));
+}
+
+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(!PageBlkback(page));
+ 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);
handle = pending_handle(req, i);
if (handle == BLKBACK_INVALID_HANDLE)
continue;
+ blkback_pagemap_clear(virt_to_page(vaddr(req, i)));
gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
GNTMAP_host_map, handle);
pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT));
seg[i].buf = map[i].dev_bus_addr |
(req->seg[i].first_sect << 9);
+ blkback_pagemap_set(vaddr_pagenr(pending_req, i),
+ virt_to_page(vaddr(pending_req, i)),
+ blkif->domid, req->handle,
+ req->seg[i].gref);
}
if (ret)
for(i = 0; i < mmap_pages; i++)
SetPageBlkback(pending_pages[i]);
+ if (blkback_pagemap_init(mmap_pages))
+ goto out_of_memory;
+
if (!pending_reqs || !pending_grant_handles || !pending_pages)
goto out_of_memory;
#include <xen/gnttab.h>
#include <xen/driver_util.h>
#include <xen/xenbus.h>
+#include "blkback-pagemap.h"
+
#define DPRINTK(_f, _a...) \
pr_debug("(file=%s, line=%d) " _f, \
void blkback_close(blkif_t *blkif);
+int blkback_pagemap_init(int);
+void blkback_pagemap_set(int, struct page *, domid_t, busid_t, grant_ref_t);
+void blkback_pagemap_clear(struct page *);
+
#endif /* __BLKIF__BACKEND__COMMON_H__ */