Commit 7ce804ed authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

page-xfer: remote-pages: allow receiving partial data

Since commit e609267f681062b4370e528a50f635222e0c2330 ("page-pipe: allow to
share pipes between page pipe buffers") the assumption that we will receive
the exact amount of pages we've requested with PS_IOV_GET does not always
hold.
In the case we serve pages data from the images using 'page-server
--lazy-page' the IOVs seen by the pagemap may cross page-pipe buffer
boundaries and read_page_pipe will clamp the pages in the response to those
boundaries.
Adjust page_server_read so it will not try to receive more pages than
page-server is going to send.
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 23d086c2
...@@ -1084,6 +1084,7 @@ out: ...@@ -1084,6 +1084,7 @@ out:
struct ps_async_read { struct ps_async_read {
unsigned long rb; /* read bytes */ unsigned long rb; /* read bytes */
unsigned long goal; unsigned long goal;
unsigned long nr_pages;
struct page_server_iov pi; struct page_server_iov pi;
void *pages; void *pages;
...@@ -1096,14 +1097,20 @@ struct ps_async_read { ...@@ -1096,14 +1097,20 @@ struct ps_async_read {
static LIST_HEAD(async_reads); static LIST_HEAD(async_reads);
static inline void async_read_set_goal(struct ps_async_read *ar, int nr_pages)
{
ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
ar->nr_pages = nr_pages;
}
static void init_ps_async_read(struct ps_async_read *ar, void *buf, static void init_ps_async_read(struct ps_async_read *ar, void *buf,
int nr_pages, ps_async_read_complete complete, void *priv) int nr_pages, ps_async_read_complete complete, void *priv)
{ {
ar->pages = buf; ar->pages = buf;
ar->rb = 0; ar->rb = 0;
ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
ar->complete = complete; ar->complete = complete;
ar->priv = priv; ar->priv = priv;
async_read_set_goal(ar, nr_pages);
} }
static int page_server_start_async_read(void *buf, int nr_pages, static int page_server_start_async_read(void *buf, int nr_pages,
...@@ -1139,6 +1146,9 @@ static int page_server_read(struct ps_async_read *ar, int flags) ...@@ -1139,6 +1146,9 @@ static int page_server_read(struct ps_async_read *ar, int flags)
buf = ((void *)&ar->pi) + ar->rb; buf = ((void *)&ar->pi) + ar->rb;
need = sizeof(ar->pi) - ar->rb; need = sizeof(ar->pi) - ar->rb;
} else { } else {
/* page-serer may return less pages than we asked for */
if (ar->pi.nr_pages < ar->nr_pages)
async_read_set_goal(ar, ar->pi.nr_pages);
/* Page(s) data itself */ /* Page(s) data itself */
buf = ar->pages + (ar->rb - sizeof(ar->pi)); buf = ar->pages + (ar->rb - sizeof(ar->pi));
need = ar->goal - ar->rb; need = ar->goal - ar->rb;
......
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