1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-20 06:50:22 +03:00

virfile: safezero: fall back to writing block by block if mmap fails

mmap can fail on 32-bit systems if we're trying to zero out a lot of data.
Fall back to using block-by-block writing in that case.  While we could map
smaller blocks it's unlikely that this code is used a lot and its easier to
just fall back to one of the existing methods.

Also modified the block-by-block zeroing to not allocate a megabyte of
zeroes if we're writing less than that.

Signed-off-by: Oskari Saarenmaa <os@ohmu.fi>
This commit is contained in:
Oskari Saarenmaa 2013-10-02 10:31:09 +03:00 committed by Michal Privoznik
parent 68cc45b6f9
commit 7dc1d4ab89

View File

@ -1032,16 +1032,18 @@ safezero(int fd, off_t offset, off_t len)
errno = ret; errno = ret;
return -1; return -1;
} }
#else #else
# ifdef HAVE_MMAP
int int
safezero(int fd, off_t offset, off_t len) safezero(int fd, off_t offset, off_t len)
{ {
static long pagemask = 0;
off_t map_skip;
int r; int r;
char *buf; char *buf;
unsigned long long remain, bytes;
# ifdef HAVE_MMAP
static long pagemask = 0;
off_t map_skip;
/* align offset and length, rounding offset down and length up */ /* align offset and length, rounding offset down and length up */
if (pagemask == 0) if (pagemask == 0)
@ -1057,30 +1059,23 @@ safezero(int fd, off_t offset, off_t len)
buf = mmap(NULL, len + map_skip, PROT_READ | PROT_WRITE, MAP_SHARED, buf = mmap(NULL, len + map_skip, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, offset - map_skip); fd, offset - map_skip);
if (buf == MAP_FAILED) if (buf != MAP_FAILED) {
return -1; memset(buf + map_skip, 0, len);
munmap(buf, len + map_skip);
memset(buf + map_skip, 0, len); return 0;
munmap(buf, len + map_skip); }
return 0; /* fall back to writing zeroes using safewrite if mmap fails (for
} * example because of virtual memory limits) */
# endif /* HAVE_MMAP */
# else /* HAVE_MMAP */
int
safezero(int fd, off_t offset, off_t len)
{
int r;
char *buf;
unsigned long long remain, bytes;
if (lseek(fd, offset, SEEK_SET) < 0) if (lseek(fd, offset, SEEK_SET) < 0)
return -1; return -1;
/* Split up the write in small chunks so as not to allocate lots of RAM */ /* Split up the write in small chunks so as not to allocate lots of RAM */
remain = len; remain = len;
bytes = 1024 * 1024; bytes = MAX(1024 * 1024, len);
r = VIR_ALLOC_N(buf, bytes); r = VIR_ALLOC_N(buf, bytes);
if (r < 0) { if (r < 0) {
@ -1104,7 +1099,6 @@ safezero(int fd, off_t offset, off_t len)
VIR_FREE(buf); VIR_FREE(buf);
return 0; return 0;
} }
# endif /* HAVE_MMAP */
#endif /* HAVE_POSIX_FALLOCATE */ #endif /* HAVE_POSIX_FALLOCATE */