]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage_backend: Fix issue with allocation of 0 length volume
authorJohn Ferlan <jferlan@redhat.com>
Wed, 9 Oct 2013 13:03:25 +0000 (09:03 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Thu, 10 Oct 2013 12:33:04 +0000 (08:33 -0400)
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).

src/storage/storage_backend.c

index 4eec0f3c6c3866e9bca277b58f5d345789a65359..c21e6eaf64d359ddac93d1f763d638e9f1492be0 100644 (file)
@@ -332,19 +332,22 @@ createRawFile(int fd, virStorageVolDefPtr vol,
 /* Avoid issues with older kernel's <linux/fs.h> namespace pollution. */
 #if HAVE_FALLOCATE - 0
     /* 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
      * to writing zeroes block by block in case fallocate isn't
      * available, and since we're going to copy data from another
      * file it doesn't make sense to write the file twice. */
-    if (fallocate(fd, 0, 0, vol->allocation) == 0) {
-        need_alloc = false;
-    } else if (errno != ENOSYS && errno != EOPNOTSUPP) {
-        ret = -errno;
-        virReportSystemError(errno,
-                             _("cannot allocate %llu bytes in file '%s'"),
-                             vol->allocation, vol->target.path);
-        goto cleanup;
+    if (vol->allocation) {
+        if (fallocate(fd, 0, 0, vol->allocation) == 0) {
+            need_alloc = false;
+        } else if (errno != ENOSYS && errno != EOPNOTSUPP) {
+            ret = -errno;
+            virReportSystemError(errno,
+                                 _("cannot allocate %llu bytes in file '%s'"),
+                                 vol->allocation, vol->target.path);
+            goto cleanup;
+        }
     }
 #endif