Commit 75b4aae5 authored by Mike Rapoport's avatar Mike Rapoport Committed by Pavel Emelyanov

pagemap: replace seek_page with seek_pagemap method

The only external users of ->seek_page method are page-xfer and uffd and
both of them are anyway interested in the entire pagemap rather than a
particular page.
The added 'skip_zero' parameter allows proper detection of zero pagemaps by
uffd.
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 7d929d2d
......@@ -53,8 +53,8 @@ struct page_read {
/* Advance page_read to the next entry (including zero pagemaps) */
int (*advance)(struct page_read *pr);
void (*close)(struct page_read *);
int (*seek_page)(struct page_read *pr, unsigned long vaddr);
int (*sync)(struct page_read *pr);
int (*seek_pagemap)(struct page_read *pr, unsigned long vaddr);
/* Private data of reader */
struct cr_img *pmi;
......
......@@ -202,7 +202,7 @@ static int check_pagehole_in_parent(struct page_read *p, struct iovec *iov)
struct iovec piov;
unsigned long pend;
ret = p->seek_page(p, off);
ret = p->seek_pagemap(p, off);
if (ret <= 0 || !p->pe) {
pr_err("Missing %lx in parent pagemap\n", off);
return -1;
......
......@@ -82,6 +82,8 @@ static int punch_hole(struct page_read *pr, unsigned long off,
return 0;
}
static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr);
int dedup_one_iovec(struct page_read *pr, struct iovec *iov)
{
unsigned long off;
......@@ -96,7 +98,7 @@ int dedup_one_iovec(struct page_read *pr, struct iovec *iov)
struct iovec tiov;
struct page_read * prp;
ret = pr->seek_page(pr, off);
ret = seek_pagemap_page(pr, off);
if (ret == 0) {
pr_warn("Missing %lx in parent pagemap\n", off);
if (off < pr->cvaddr && pr->cvaddr < iov_end)
......@@ -172,7 +174,7 @@ static void skip_pagemap_pages(struct page_read *pr, unsigned long len)
pr->cvaddr += len;
}
static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr)
static int seek_pagemap(struct page_read *pr, unsigned long vaddr)
{
if (!pr->pe)
advance(pr);
......@@ -186,7 +188,7 @@ static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr)
break;
if (vaddr >= start && vaddr < end) {
skip_pagemap_pages(pr, vaddr - pr->cvaddr);
skip_pagemap_pages(pr, start - pr->cvaddr);
return 1;
}
......@@ -197,6 +199,16 @@ static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr)
return 0;
}
static int seek_pagemap_page(struct page_read *pr, unsigned long vaddr)
{
if (seek_pagemap(pr, vaddr)) {
skip_pagemap_pages(pr, vaddr - pr->cvaddr);
return 1;
}
return 0;
}
static inline void pagemap_bound_check(PagemapEntry *pe, unsigned long vaddr, int nr)
{
if (vaddr < pe->vaddr || (vaddr - pe->vaddr) / PAGE_SIZE + nr > pe->nr_pages) {
......@@ -620,8 +632,8 @@ int open_page_read_at(int dfd, int pid, struct page_read *pr, int pr_flags)
pr->read_pages = read_pagemap_page;
pr->advance = advance;
pr->close = close_page_read;
pr->seek_page = seek_pagemap_page;
pr->sync = process_async_reads;
pr->seek_pagemap = seek_pagemap;
pr->id = ids++;
pr_debug("Opened page read %u (parent %u)\n",
......
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