<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014-03-04 9:30 GMT+04:00 Pavel Tikhomirov <span dir="ltr"><<a href="mailto:snorcht@gmail.com" target="_blank">snorcht@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014-03-03 17:51 GMT+04:00 Tikhomirov Pavel <span dir="ltr"><<a href="mailto:snorcht@gmail.com" target="_blank">snorcht@gmail.com</a>></span>:<div><div class="h5">
<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
when decide that data is no longer needed, there are two cases:<br>
1. if data neighbours previous block of "no needed" data, extend bunch<br>
block(it holds begining and size of concequent "no needed" data) by<br>
length of curent block and go next.<br>
2. if data not neighbours bunch block(or bunch block size is bigger<br>
than MAX_BUNCH_SIZE), than punch bunch block and set bunch block<br>
to curent block.<br>
<br>
in the end make cleanup to punch last bunch block.<br>
<br>
Signed-off-by: Tikhomirov Pavel <<a href="mailto:snorcht@gmail.com" target="_blank">snorcht@gmail.com</a>><br>
---<br>
cr-dedup.c | 34 ++++++++++++++++++++++++++--------<br>
include/page-read.h | 5 ++++-<br>
page-read.c | 14 +++++++++++++-<br>
3 files changed, 43 insertions(+), 10 deletions(-)<br>
<br>
diff --git a/cr-dedup.c b/cr-dedup.c<br>
index 6f059d1..9d269d2 100644<br>
--- a/cr-dedup.c<br>
+++ b/cr-dedup.c<br>
@@ -7,6 +7,8 @@<br>
#include "page-read.h"<br>
#include "restorer.h"<br>
<br>
+#define MAX_BUNCH_SIZE 256<br>
+<br>
static int cr_dedup_one_pagemap(int pid);<br>
<br>
int cr_dedup(void)<br>
@@ -101,15 +103,30 @@ exit:<br>
return 0;<br>
}<br>
<br>
-int punch_hole(int fd, unsigned long off, unsigned long len)<br>
+int punch_hole(int fd, unsigned long off, unsigned long len,<br>
+ struct iovec * bunch, bool cleanup, int pr_id)<br>
{<br>
int ret;<br>
- pr_debug("Punch!/%lu/%lu/\n", off, len);<br>
- ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,<br>
- off, len);<br>
- if (ret != 0) {<br>
- pr_perror("Error punching hole");<br>
- return -1;<br>
+<br>
+ if ((unsigned long)bunch->iov_base + bunch->iov_len == off && !cleanup<br>
+ && bunch->iov_len < MAX_BUNCH_SIZE * PAGE_SIZE) {<br>
+ pr_debug("pr%d:Extend bunch len from %lx to %lx\n", pr_id,<br>
+ bunch->iov_len, bunch->iov_len + len);<br>
+ bunch->iov_len += len;<br>
+ } else {<br>
+ if (bunch->iov_len > 0) {<br>
+ pr_debug("Punch!/%lx/%lx/\n", (unsigned long)bunch->iov_base, bunch->iov_len);<br>
+ ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,<br>
+ (unsigned long)bunch->iov_base, bunch->iov_len);<br>
+ if (ret != 0) {<br>
+ pr_perror("Error punching hole");<br>
+ return -1;<br>
+ }<br>
+ }<br>
+ bunch->iov_base = (void *)off;<br>
+ bunch->iov_len = len;<br>
+ pr_debug("pr%d:New bunch/%lx/%lx/\n", pr_id,<br>
+ (unsigned long)bunch->iov_base, bunch->iov_len);<br>
}<br>
return 0;<br>
}<br>
@@ -146,7 +163,8 @@ int dedup_one_iovec(struct page_read *pr, struct iovec *iov)<br>
piov_end = (unsigned long)piov.iov_base + piov.iov_len;<br>
off_real = lseek(pr->fd_pg, 0, SEEK_CUR);<br>
if (!pr->pe->in_parent) {<br>
- ret = punch_hole(pr->fd_pg, off_real, min(piov_end, iov_end) - off);<br>
+ ret = punch_hole(pr->fd_pg, off_real, min(piov_end, iov_end) - off,<br>
+ &pr->bunch, false, pr->id);<br>
if (ret == -1)<br>
return ret;<br>
}<br>
diff --git a/include/page-read.h b/include/page-read.h<br>
index 8b467c6..28435c7 100644<br>
--- a/include/page-read.h<br>
+++ b/include/page-read.h<br>
@@ -63,6 +63,8 @@ struct page_read {<br>
read_pagemap_page */<br>
unsigned long cvaddr; /* vaddr we are on */<br>
<br>
+ struct iovec bunch; /* record consequent neighbour<br>
+ iovecs to punch together */<br>
unsigned id; /* for logging */<br>
};<br>
<br>
@@ -72,5 +74,6 @@ extern void pagemap2iovec(PagemapEntry *pe, struct iovec *iov);<br>
extern int seek_pagemap_page(struct page_read *pr, unsigned long vaddr, bool warn);<br>
<br>
extern int dedup_one_iovec(struct page_read *pr, struct iovec *iov);<br>
-extern int punch_hole(int fd, unsigned long off, unsigned long len);<br>
+extern int punch_hole(int fd, unsigned long off, unsigned long len,<br>
+ struct iovec * bunch, bool cleanup, int pr_id);<br>
#endif /* __CR_PAGE_READ_H__ */<br>
diff --git a/page-read.c b/page-read.c<br>
index e2514d6..0fd3464 100644<br>
--- a/page-read.c<br>
+++ b/page-read.c<br>
@@ -149,7 +149,8 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, void *bu<br>
}<br>
<br>
if (opts.auto_dedup) {<br>
- ret = punch_hole(pr->fd_pg, current_vaddr, (unsigned int)PAGE_SIZE);<br>
+ ret = punch_hole(pr->fd_pg, current_vaddr, (unsigned int)PAGE_SIZE,<br>
+ &pr->bunch, false, pr->id);<br>
if (ret == -1) {<br>
return -1;<br>
}<br>
@@ -163,6 +164,15 @@ static int read_pagemap_page(struct page_read *pr, unsigned long vaddr, void *bu<br>
<br>
static void close_page_read(struct page_read *pr)<br>
{<br>
+ int ret;<br>
+ if (pr->bunch.iov_len > 0) {<br>
+ ret = punch_hole(pr->fd_pg, 0, 0, &pr->bunch, true, pr->id);<br>
+ if (ret == -1)<br>
+ return;<br></blockquote><div><br></div></div></div><div>Here I'm not sure if I can do something like this, and what will be better way to do it.</div><div>But this place is really suitable to make cleanup. So give me an advice, Thanks!</div>
<div class="">
<div></div></div></div></div></div></blockquote><div><br></div><div>Make <span style="color:rgb(80,0,80)">close_page_read </span><font color="#000000">return int? Or it is unappropriate to make cleanup in close func? </font></div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div class=""><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+<br>
+ pr->bunch.iov_len = 0;<br>
+ }<br>
+<br>
if (pr->parent) {<br>
close_page_read(pr->parent);<br>
xfree(pr->parent);<br>
@@ -207,6 +217,8 @@ err_cl:<br>
int open_page_read_at(int dfd, int pid, struct page_read *pr, int flags)<br>
{<br>
pr->pe = NULL;<br>
+ pr->bunch.iov_len = 0;<br>
+ pr->bunch.iov_base = NULL;<br>
<br>
pr->fd = open_image_at(dfd, CR_FD_PAGEMAP, O_RSTR, (long)pid);<br>
if (pr->fd < 0) {<br>
<span><font color="#888888">--<br>
1.8.3.2<br>
<br>
</font></span></blockquote></div></div><br></div></div>
</blockquote></div><br></div></div>