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:
parent
68cc45b6f9
commit
7dc1d4ab89
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user