<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2014-03-03 17:51 GMT+04:00 Tikhomirov Pavel <span dir="ltr">&lt;<a href="mailto:snorcht@gmail.com" target="_blank">snorcht@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
when decide that data is no longer needed, there are two cases:<br>
1. if data neighbours previous block of &quot;no needed&quot; data, extend bunch<br>
block(it holds begining and size of concequent &quot;no needed&quot; 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 &lt;<a href="mailto:snorcht@gmail.com">snorcht@gmail.com</a>&gt;<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 &quot;page-read.h&quot;<br>
 #include &quot;restorer.h&quot;<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(&quot;Punch!/%lu/%lu/\n&quot;, off, len);<br>
-       ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,<br>
-                       off, len);<br>
-       if (ret != 0) {<br>
-               pr_perror(&quot;Error punching hole&quot;);<br>
-               return -1;<br>
+<br>
+       if ((unsigned long)bunch-&gt;iov_base + bunch-&gt;iov_len == off &amp;&amp; !cleanup<br>
+           &amp;&amp; bunch-&gt;iov_len &lt; MAX_BUNCH_SIZE * PAGE_SIZE) {<br>
+               pr_debug(&quot;pr%d:Extend bunch len from %lx to %lx\n&quot;, pr_id,<br>
+                        bunch-&gt;iov_len, bunch-&gt;iov_len + len);<br>
+               bunch-&gt;iov_len += len;<br>
+       } else {<br>
+               if (bunch-&gt;iov_len &gt; 0) {<br>
+                       pr_debug(&quot;Punch!/%lx/%lx/\n&quot;, (unsigned long)bunch-&gt;iov_base, bunch-&gt;iov_len);<br>
+                       ret = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,<br>
+                                       (unsigned long)bunch-&gt;iov_base, bunch-&gt;iov_len);<br>
+                       if (ret != 0) {<br>
+                               pr_perror(&quot;Error punching hole&quot;);<br>
+                               return -1;<br>
+                       }<br>
+               }<br>
+               bunch-&gt;iov_base = (void *)off;<br>
+               bunch-&gt;iov_len = len;<br>
+               pr_debug(&quot;pr%d:New bunch/%lx/%lx/\n&quot;, pr_id,<br>
+                        (unsigned long)bunch-&gt;iov_base, bunch-&gt;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-&gt;fd_pg, 0, SEEK_CUR);<br>
                if (!pr-&gt;pe-&gt;in_parent) {<br>
-                       ret = punch_hole(pr-&gt;fd_pg, off_real, min(piov_end, iov_end) - off);<br>
+                       ret = punch_hole(pr-&gt;fd_pg, off_real, min(piov_end, iov_end) - off,<br>
+                                        &amp;pr-&gt;bunch, false, pr-&gt;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-&gt;fd_pg, current_vaddr, (unsigned int)PAGE_SIZE);<br>
+                       ret = punch_hole(pr-&gt;fd_pg, current_vaddr, (unsigned int)PAGE_SIZE,<br>
+                                        &amp;pr-&gt;bunch, false, pr-&gt;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-&gt;bunch.iov_len &gt; 0) {<br>
+               ret = punch_hole(pr-&gt;fd_pg, 0, 0, &amp;pr-&gt;bunch, true, pr-&gt;id);<br>
+               if (ret == -1)<br>
+                       return;<br></blockquote><div><br></div><div>Here I&#39;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> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+               pr-&gt;bunch.iov_len = 0;<br>
+       }<br>
+<br>
        if (pr-&gt;parent) {<br>
                close_page_read(pr-&gt;parent);<br>
                xfree(pr-&gt;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-&gt;pe = NULL;<br>
+       pr-&gt;bunch.iov_len = 0;<br>
+       pr-&gt;bunch.iov_base = NULL;<br>
<br>
        pr-&gt;fd = open_image_at(dfd, CR_FD_PAGEMAP, O_RSTR, (long)pid);<br>
        if (pr-&gt;fd &lt; 0) {<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.2<br>
<br>
</font></span></blockquote></div><br></div></div>