Commit 4ea4653c authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

xfer: Merge write_hole and _pagemap callbacks

They are now the same and PE_PRESENT bit helps us distinguish
holes from pagemaps having pages inside.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Acked-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
parent 6d2b35ce
...@@ -15,8 +15,6 @@ struct page_xfer { ...@@ -15,8 +15,6 @@ struct page_xfer {
int (*write_pagemap)(struct page_xfer *self, struct iovec *iov, u32 flags); int (*write_pagemap)(struct page_xfer *self, struct iovec *iov, u32 flags);
/* transfers pages related to previous pagemap */ /* transfers pages related to previous pagemap */
int (*write_pages)(struct page_xfer *self, int pipe, unsigned long len); int (*write_pages)(struct page_xfer *self, int pipe, unsigned long len);
/* transfers one hole -- vaddr:len entry w/o pages */
int (*write_hole)(struct page_xfer *self, struct iovec *iov, u32 flags);
void (*close)(struct page_xfer *self); void (*close)(struct page_xfer *self);
/* private data for every page-xfer engine */ /* private data for every page-xfer engine */
......
...@@ -144,22 +144,7 @@ static inline int send_psi(int sk, u32 cmd, u32 nr_pages, u64 vaddr, u64 dst_id) ...@@ -144,22 +144,7 @@ static inline int send_psi(int sk, u32 cmd, u32 nr_pages, u64 vaddr, u64 dst_id)
return 0; return 0;
} }
static inline int send_iov(int sk, u32 cmd, u64 dst_id, struct iovec *iov)
{
u64 vaddr = encode_pointer(iov->iov_base);
u32 nr_pages = iov->iov_len / PAGE_SIZE;
return send_psi(sk, cmd, nr_pages, vaddr, dst_id);
}
/* page-server xfer */ /* page-server xfer */
static int write_pagemap_to_server(struct page_xfer *xfer, struct iovec *iov,
u32 flags)
{
return send_iov(xfer->sk, encode_ps_cmd(PS_IOV_ADD, flags),
xfer->dst_id, iov);
}
static int write_pages_to_server(struct page_xfer *xfer, static int write_pages_to_server(struct page_xfer *xfer,
int p, unsigned long len) int p, unsigned long len)
{ {
...@@ -173,12 +158,13 @@ static int write_pages_to_server(struct page_xfer *xfer, ...@@ -173,12 +158,13 @@ static int write_pages_to_server(struct page_xfer *xfer,
return 0; return 0;
} }
static int write_hole_to_server(struct page_xfer *xfer, struct iovec *iov, u32 flags) static int write_pagemap_to_server(struct page_xfer *xfer, struct iovec *iov, u32 flags)
{ {
u32 cmd = 0; u32 cmd = 0;
BUG_ON(flags & PE_PRESENT);
if (flags & PE_PARENT) if (flags & PE_PRESENT)
cmd = encode_ps_cmd(PS_IOV_ADD, flags);
else if (flags & PE_PARENT)
cmd = PS_IOV_HOLE; cmd = PS_IOV_HOLE;
else if (flags & PE_LAZY) else if (flags & PE_LAZY)
cmd = PS_IOV_LAZY; cmd = PS_IOV_LAZY;
...@@ -187,7 +173,9 @@ static int write_hole_to_server(struct page_xfer *xfer, struct iovec *iov, u32 f ...@@ -187,7 +173,9 @@ static int write_hole_to_server(struct page_xfer *xfer, struct iovec *iov, u32 f
else else
BUG(); BUG();
return send_iov(xfer->sk, cmd, xfer->dst_id, iov); return send_psi(xfer->sk, cmd,
iov->iov_len / PAGE_SIZE, encode_pointer(iov->iov_base),
xfer->dst_id);
} }
static void close_server_xfer(struct page_xfer *xfer) static void close_server_xfer(struct page_xfer *xfer)
...@@ -202,7 +190,6 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -202,7 +190,6 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
xfer->sk = page_server_sk; xfer->sk = page_server_sk;
xfer->write_pagemap = write_pagemap_to_server; xfer->write_pagemap = write_pagemap_to_server;
xfer->write_pages = write_pages_to_server; xfer->write_pages = write_pages_to_server;
xfer->write_hole = write_hole_to_server;
xfer->close = close_server_xfer; xfer->close = close_server_xfer;
xfer->dst_id = encode_pm(fd_type, id); xfer->dst_id = encode_pm(fd_type, id);
xfer->parent = NULL; xfer->parent = NULL;
...@@ -227,27 +214,6 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -227,27 +214,6 @@ static int open_page_server_xfer(struct page_xfer *xfer, int fd_type, long id)
} }
/* local xfer */ /* local xfer */
static int write_pagemap_loc(struct page_xfer *xfer, struct iovec *iov,
u32 flags)
{
int ret;
PagemapEntry pe = PAGEMAP_ENTRY__INIT;
pe.vaddr = encode_pointer(iov->iov_base);
pe.nr_pages = iov->iov_len / PAGE_SIZE;
pe.has_flags = true;
pe.flags = flags;
if (opts.auto_dedup && xfer->parent != NULL) {
ret = dedup_one_iovec(xfer->parent, pe.vaddr,
pagemap_len(&pe));
if (ret == -1) {
pr_perror("Auto-deduplication failed");
return ret;
}
}
return pb_write_one(xfer->pmi, &pe, PB_PAGEMAP);
}
static int write_pages_loc(struct page_xfer *xfer, static int write_pages_loc(struct page_xfer *xfer,
int p, unsigned long len) int p, unsigned long len)
{ {
...@@ -314,21 +280,27 @@ static int check_pagehole_in_parent(struct page_read *p, struct iovec *iov) ...@@ -314,21 +280,27 @@ static int check_pagehole_in_parent(struct page_read *p, struct iovec *iov)
} }
} }
static int write_hole_loc(struct page_xfer *xfer, struct iovec *iov, u32 flags) static int write_pagemap_loc(struct page_xfer *xfer, struct iovec *iov, u32 flags)
{ {
int ret;
PagemapEntry pe = PAGEMAP_ENTRY__INIT; PagemapEntry pe = PAGEMAP_ENTRY__INIT;
BUG_ON(flags & PE_PRESENT);
pe.vaddr = encode_pointer(iov->iov_base); pe.vaddr = encode_pointer(iov->iov_base);
pe.nr_pages = iov->iov_len / PAGE_SIZE; pe.nr_pages = iov->iov_len / PAGE_SIZE;
pe.has_flags = true; pe.has_flags = true;
pe.flags = flags; pe.flags = flags;
if (flags & PE_PARENT) { if (flags & PE_PRESENT) {
if (opts.auto_dedup && xfer->parent != NULL) {
ret = dedup_one_iovec(xfer->parent, pe.vaddr,
pagemap_len(&pe));
if (ret == -1) {
pr_perror("Auto-deduplication failed");
return ret;
}
}
} else if (flags & PE_PARENT) {
if (xfer->parent != NULL) { if (xfer->parent != NULL) {
int ret;
ret = check_pagehole_in_parent(xfer->parent, iov); ret = check_pagehole_in_parent(xfer->parent, iov);
if (ret) { if (ret) {
pr_err("Hole %p/%zu not found in parent\n", pr_err("Hole %p/%zu not found in parent\n",
...@@ -406,7 +378,6 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id) ...@@ -406,7 +378,6 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id)
out: out:
xfer->write_pagemap = write_pagemap_loc; xfer->write_pagemap = write_pagemap_loc;
xfer->write_pages = write_pages_loc; xfer->write_pages = write_pages_loc;
xfer->write_hole = write_hole_loc;
xfer->close = close_page_xfer; xfer->close = close_page_xfer;
return 0; return 0;
} }
...@@ -427,7 +398,7 @@ static int page_xfer_dump_hole(struct page_xfer *xfer, ...@@ -427,7 +398,7 @@ static int page_xfer_dump_hole(struct page_xfer *xfer,
pr_debug("\th %p [%u]\n", hole->iov_base, pr_debug("\th %p [%u]\n", hole->iov_base,
(unsigned int)(hole->iov_len / PAGE_SIZE)); (unsigned int)(hole->iov_len / PAGE_SIZE));
if (xfer->write_hole(xfer, hole, flags)) if (xfer->write_pagemap(xfer, hole, flags))
return -1; return -1;
return 0; return 0;
...@@ -497,7 +468,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp, ...@@ -497,7 +468,7 @@ int page_xfer_dump_pages(struct page_xfer *xfer, struct page_pipe *pp,
if (ppb->flags & PPB_LAZY) { if (ppb->flags & PPB_LAZY) {
if (!dump_lazy) { if (!dump_lazy) {
if (xfer->write_hole(xfer, &iov, PE_LAZY)) if (xfer->write_pagemap(xfer, &iov, PE_LAZY))
return -1; return -1;
continue; continue;
} else { } else {
...@@ -726,7 +697,7 @@ static int page_server_hole(int sk, struct page_server_iov *pi, u32 flags) ...@@ -726,7 +697,7 @@ static int page_server_hole(int sk, struct page_server_iov *pi, u32 flags)
return -1; return -1;
psi2iovec(pi, &iov); psi2iovec(pi, &iov);
if (lxfer->write_hole(lxfer, &iov, flags)) if (lxfer->write_pagemap(lxfer, &iov, flags))
return -1; return -1;
return 0; 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