Commit 7592d28d authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Pavel Emelyanov

page-xfer: Add helper for dumping a single hole

[xemul: This is an extract from the patch "page-xfer: dump compatible iovec"
 to make rebase simpler ]

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 9a97e0ca
......@@ -320,61 +320,71 @@ int open_page_xfer(struct page_xfer *xfer, int fd_type, long id)
return open_page_local_xfer(xfer, fd_type, id);
}
static int page_xfer_dump_hole(struct page_xfer *xfer,
struct iovec *hole, unsigned long off)
{
BUG_ON(hole->iov_base < (void *)off);
hole->iov_base -= off;
pr_debug("\th %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole))
return -1;
return 0;
}
static struct iovec get_iov(struct iovec *iovs, unsigned int n)
{
return iovs[n];
}
int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
unsigned long off)
{
struct page_pipe_buf *ppb;
struct iovec *hole = NULL;
unsigned int cur_hole = 0;
int ret;
pr_debug("Transfering pages:\n");
if (pp->free_hole)
hole = &pp->holes[0];
list_for_each_entry(ppb, &pp->bufs, l) {
int i;
unsigned int i;
pr_debug("\tbuf %d/%d\n", ppb->pages_in, ppb->nr_segs);
for (i = 0; i < ppb->nr_segs; i++) {
struct iovec *iov = &ppb->iov[i];
while (hole && (hole->iov_base < iov->iov_base)) {
BUG_ON(hole->iov_base < (void *)off);
hole->iov_base -= off;
pr_debug("\th %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole))
return -1;
hole++;
if (hole >= &pp->holes[pp->free_hole])
hole = NULL;
struct iovec iov = get_iov(ppb->iov, i, pp->compat_iov);
for (; cur_hole < pp->free_hole ; cur_hole++) {
struct iovec hole = get_iov(pp->holes, cur_hole,
pp->compat_iov);
if (hole.iov_base < iov.iov_base)
break;
ret = page_xfer_dump_hole(xfer, &hole, off);
if (ret)
return ret;
}
BUG_ON(iov->iov_base < (void *)off);
iov->iov_base -= off;
pr_debug("\tp %p [%u]\n", iov->iov_base,
(unsigned int)(iov->iov_len / PAGE_SIZE));
BUG_ON(iov.iov_base < (void *)off);
iov.iov_base -= off;
pr_debug("\tp %p [%u]\n", iov.iov_base,
(unsigned int)(iov.iov_len / PAGE_SIZE));
if (xfer->write_pagemap(xfer, iov))
if (xfer->write_pagemap(xfer, &iov))
return -1;
if (xfer->write_pages(xfer, ppb->p[0], iov->iov_len))
if (xfer->write_pages(xfer, ppb->p[0], iov.iov_len))
return -1;
}
}
while (hole) {
BUG_ON(hole->iov_base < (void *)off);
hole->iov_base -= off;
pr_debug("\th* %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole))
return -1;
for (; cur_hole < pp->free_hole ; cur_hole++) {
struct iovec hole = get_iov(pp->holes, cur_hole, pp->compat_iov);
hole++;
if (hole >= &pp->holes[pp->free_hole])
hole = NULL;
ret = page_xfer_dump_hole(xfer, &hole, off);
if (ret)
return ret;
}
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment