storage_backend: Fix issue with allocation of 0 length volume

Commit id '532fef36' added a call to fallocate() and some error
handling based on whether or not the function existed. This new
call resulted in libvirt-cim/cimtest failures when attempting to
create a volume with "0" (zero) allocation value. The failure is
logged as:

Oct  9 07:51:33 localhost libvirtd[8030]: cannot allocate 0 bytes in
file '/var/lib/libvirt/images/cimtest-vol.img': Invalid argument

This can also be seen with virsh vol-create-as:

error: Failed to create vol test
error: cannot allocate 0 bytes in file '/home/vm-images/test': Invalid
argument

error: Failed to create vol test
error: cannot allocate 0 bytes in file '/home/vm-images/test': Invalid
argument

It turns out fallocate() will return EINVAL when the incoming 'len'
(or allocation) value is 0 (or less).
This commit is contained in:
John Ferlan 2013-10-09 09:03:25 -04:00
parent 9c228e0817
commit 77fb4c4f9e

View File

@ -332,11 +332,13 @@ createRawFile(int fd, virStorageVolDefPtr vol,
/* Avoid issues with older kernel's <linux/fs.h> namespace pollution. */ /* Avoid issues with older kernel's <linux/fs.h> namespace pollution. */
#if HAVE_FALLOCATE - 0 #if HAVE_FALLOCATE - 0
/* Try to preallocate all requested disk space, but fall back to /* Try to preallocate all requested disk space, but fall back to
* other methods if this fails with ENOSYS or EOPNOTSUPP. * other methods if this fails with ENOSYS or EOPNOTSUPP. If allocation
* is 0 (or less than 0), then fallocate will fail with EINVAL.
* NOTE: do not use posix_fallocate; posix_fallocate falls back * NOTE: do not use posix_fallocate; posix_fallocate falls back
* to writing zeroes block by block in case fallocate isn't * to writing zeroes block by block in case fallocate isn't
* available, and since we're going to copy data from another * available, and since we're going to copy data from another
* file it doesn't make sense to write the file twice. */ * file it doesn't make sense to write the file twice. */
if (vol->allocation) {
if (fallocate(fd, 0, 0, vol->allocation) == 0) { if (fallocate(fd, 0, 0, vol->allocation) == 0) {
need_alloc = false; need_alloc = false;
} else if (errno != ENOSYS && errno != EOPNOTSUPP) { } else if (errno != ENOSYS && errno != EOPNOTSUPP) {
@ -346,6 +348,7 @@ createRawFile(int fd, virStorageVolDefPtr vol,
vol->allocation, vol->target.path); vol->allocation, vol->target.path);
goto cleanup; goto cleanup;
} }
}
#endif #endif
remain = vol->allocation; remain = vol->allocation;