Commit eff067a3 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

lazy-pages: split_iov: always create the new iov above the one being split

Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 6115934b
...@@ -390,7 +390,7 @@ static struct lazy_iov *find_iov(struct lazy_pages_info *lpi, ...@@ -390,7 +390,7 @@ static struct lazy_iov *find_iov(struct lazy_pages_info *lpi,
return NULL; return NULL;
} }
static int split_iov(struct lazy_iov *iov, unsigned long addr, bool new_below) static int split_iov(struct lazy_iov *iov, unsigned long addr)
{ {
struct lazy_iov *new; struct lazy_iov *new;
...@@ -398,21 +398,11 @@ static int split_iov(struct lazy_iov *iov, unsigned long addr, bool new_below) ...@@ -398,21 +398,11 @@ static int split_iov(struct lazy_iov *iov, unsigned long addr, bool new_below)
if (!new) if (!new)
return -1; return -1;
if (new_below) { new->base = addr;
new->base = iov->base; new->img_base = iov->img_base + addr - iov->base;
new->img_base = iov->img_base; new->len = iov->len - (addr - iov->base);
new->len = addr - iov->base; iov->len -= new->len;
iov->base = addr; list_add(&new->l, &iov->l);
iov->img_base += new->len;
iov->len -= new->len;
list_add_tail(&new->l, &iov->l);
} else {
new->base = addr;
new->img_base = iov->img_base + addr - iov->base;
new->len = iov->len - (addr - iov->base);
iov->len -= new->len;
list_add(&new->l, &iov->l);
}
return 0; return 0;
} }
...@@ -485,7 +475,7 @@ static int drop_iovs(struct lazy_pages_info *lpi, unsigned long addr, int len) ...@@ -485,7 +475,7 @@ static int drop_iovs(struct lazy_pages_info *lpi, unsigned long addr, int len)
iov->img_base += len; iov->img_base += len;
iov->len -= len; iov->len -= len;
} else { } else {
if (split_iov(iov, addr + len, false)) if (split_iov(iov, addr + len))
return -1; return -1;
iov->len -= len; iov->len -= len;
} }
...@@ -533,14 +523,18 @@ static int remap_iovs(struct lazy_pages_info *lpi, unsigned long from, ...@@ -533,14 +523,18 @@ static int remap_iovs(struct lazy_pages_info *lpi, unsigned long from,
from = iov->base; from = iov->base;
} }
if (from > iov->base) if (from > iov->base) {
if (split_iov(iov, from, true)) if (split_iov(iov, from))
return -1;
if (from + len < iov_end)
if (split_iov(iov, from + len, false))
return -1; return -1;
list_safe_reset_next(iov, n, l);
continue;
}
list_safe_reset_next(iov, n, l); if (from + len < iov_end) {
if (split_iov(iov, from + len))
return -1;
list_safe_reset_next(iov, n, l);
}
/* here we have iov->base = from, iov_end <= from + len */ /* here we have iov->base = from, iov_end <= from + len */
from = iov_end; from = iov_end;
......
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