]> xenbits.xensource.com Git - libvirt.git/commitdiff
virfile: safezero: align mmap offset to page size
authorOskari Saarenmaa <os@ohmu.fi>
Mon, 30 Sep 2013 11:01:45 +0000 (14:01 +0300)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 30 Sep 2013 13:18:13 +0000 (15:18 +0200)
mmap's offset must be aligned to page size or mapping will fail.
mmap-based safezero is only used if posix_fallocate isn't available.

Signed-off-by: Oskari Saarenmaa <os@ohmu.fi>
src/util/virfile.c

index 20ca89fd564db2d982608d8df619c0215a41ea0e..16f8101511a557b57738726587ca2f8998c57abf 100644 (file)
@@ -1038,9 +1038,16 @@ safezero(int fd, off_t offset, off_t len)
 int
 safezero(int fd, off_t offset, off_t len)
 {
+    static long pagemask = 0;
+    off_t map_skip;
     int r;
     char *buf;
 
+    /* align offset and length, rounding offset down and length up */
+    if (pagemask == 0)
+        pagemask = ~(sysconf(_SC_PAGESIZE) - 1);
+    map_skip = offset - (offset & pagemask);
+
     /* memset wants the mmap'ed file to be present on disk so create a
      * sparse file
      */
@@ -1048,12 +1055,13 @@ safezero(int fd, off_t offset, off_t len)
     if (r < 0)
         return -1;
 
-    buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
+    buf = mmap(NULL, len + map_skip, PROT_READ | PROT_WRITE, MAP_SHARED,
+               fd, offset - map_skip);
     if (buf == MAP_FAILED)
         return -1;
 
-    memset(buf, 0, len);
-    munmap(buf, len);
+    memset(buf + map_skip, 0, len);
+    munmap(buf, len + map_skip);
 
     return 0;
 }