Skip to content
  • Fam Zheng's avatar
    c6ac36e1
    vmdk: Optimize cluster allocation · c6ac36e1
    Fam Zheng authored
    
    
    This drops the unnecessary bdrv_truncate() from, and also improves,
    cluster allocation code path.
    
    Before, when we need a new cluster, get_cluster_offset truncates the
    image to bdrv_getlength() + cluster_size, and returns the offset of
    added area, i.e. the image length before truncating.
    
    This is not efficient, so it's now rewritten as:
    
      - Save the extent file length when opening.
    
      - When allocating cluster, use the saved length as cluster offset.
    
      - Don't truncate image, because we'll anyway write data there: just
        write any data at the EOF position, in descending priority:
    
        * New user data (cluster allocation happens in a write request).
    
        * Filling data in the beginning and/or ending of the new cluster, if
          not covered by user data: either backing file content (COW), or
          zero for standalone images.
    
    One major benifit of this change is, on host mounted NFS images, even
    over a fast network, ftruncate is slow (see the example below). This
    change significantly speeds up cluster allocation. Comparing by
    converting a cirros image (296M) to VMDK on an NFS mount point, over
    1Gbe LAN:
    
        $ time qemu-img convert cirros-0.3.1.img /mnt/a.raw -O vmdk
    
        Before:
            real    0m21.796s
            user    0m0.130s
            sys     0m0.483s
    
        After:
            real    0m2.017s
            user    0m0.047s
            sys     0m0.190s
    
    We also get rid of unchecked bdrv_getlength() and bdrv_truncate(), and
    get a little more documentation in function comments.
    
    Tested that this passes qemu-iotests for all VMDK subformats.
    
    Signed-off-by: default avatarFam Zheng <famz@redhat.com>
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    c6ac36e1
    vmdk: Optimize cluster allocation
    Fam Zheng authored
    
    
    This drops the unnecessary bdrv_truncate() from, and also improves,
    cluster allocation code path.
    
    Before, when we need a new cluster, get_cluster_offset truncates the
    image to bdrv_getlength() + cluster_size, and returns the offset of
    added area, i.e. the image length before truncating.
    
    This is not efficient, so it's now rewritten as:
    
      - Save the extent file length when opening.
    
      - When allocating cluster, use the saved length as cluster offset.
    
      - Don't truncate image, because we'll anyway write data there: just
        write any data at the EOF position, in descending priority:
    
        * New user data (cluster allocation happens in a write request).
    
        * Filling data in the beginning and/or ending of the new cluster, if
          not covered by user data: either backing file content (COW), or
          zero for standalone images.
    
    One major benifit of this change is, on host mounted NFS images, even
    over a fast network, ftruncate is slow (see the example below). This
    change significantly speeds up cluster allocation. Comparing by
    converting a cirros image (296M) to VMDK on an NFS mount point, over
    1Gbe LAN:
    
        $ time qemu-img convert cirros-0.3.1.img /mnt/a.raw -O vmdk
    
        Before:
            real    0m21.796s
            user    0m0.130s
            sys     0m0.483s
    
        After:
            real    0m2.017s
            user    0m0.047s
            sys     0m0.190s
    
    We also get rid of unchecked bdrv_getlength() and bdrv_truncate(), and
    get a little more documentation in function comments.
    
    Tested that this passes qemu-iotests for all VMDK subformats.
    
    Signed-off-by: default avatarFam Zheng <famz@redhat.com>
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Loading