Skip to content
  • Kevin Wolf's avatar
    b94a2610
    block: Avoid unecessary drv->bdrv_getlength() calls · b94a2610
    Kevin Wolf authored
    
    
    The block layer generally keeps the size of an image cached in
    bs->total_sectors so that it doesn't have to perform expensive
    operations to get the size whenever it needs it.
    
    This doesn't work however when using a backend that can change its size
    without qemu being aware of it, i.e. passthrough of removable media like
    CD-ROMs or floppy disks. For this reason, the caching is disabled when a
    removable device is used.
    
    It is obvious that checking whether the _guest_ device has removable
    media isn't the right thing to do when we want to know whether the size
    of the host backend can change. To make things worse, non-top-level
    BlockDriverStates never have any device attached, which makes qemu
    assume they are removable, so drv->bdrv_getlength() is always called on
    the protocol layer. In the case of raw-posix, this causes unnecessary
    lseek() system calls, which turned out to be rather expensive.
    
    This patch completely changes the logic and disables bs->total_sectors
    caching only for certain block driver types, for which a size change is
    expected: host_cdrom and host_floppy on POSIX, host_device on win32; also
    the raw format in case it sits on top of one of these protocols, but in
    the common case the nested bdrv_getlength() call on the protocol driver
    will use the cache again and avoid an expensive drv->bdrv_getlength()
    call.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    b94a2610
    block: Avoid unecessary drv->bdrv_getlength() calls
    Kevin Wolf authored
    
    
    The block layer generally keeps the size of an image cached in
    bs->total_sectors so that it doesn't have to perform expensive
    operations to get the size whenever it needs it.
    
    This doesn't work however when using a backend that can change its size
    without qemu being aware of it, i.e. passthrough of removable media like
    CD-ROMs or floppy disks. For this reason, the caching is disabled when a
    removable device is used.
    
    It is obvious that checking whether the _guest_ device has removable
    media isn't the right thing to do when we want to know whether the size
    of the host backend can change. To make things worse, non-top-level
    BlockDriverStates never have any device attached, which makes qemu
    assume they are removable, so drv->bdrv_getlength() is always called on
    the protocol layer. In the case of raw-posix, this causes unnecessary
    lseek() system calls, which turned out to be rather expensive.
    
    This patch completely changes the logic and disables bs->total_sectors
    caching only for certain block driver types, for which a size change is
    expected: host_cdrom and host_floppy on POSIX, host_device on win32; also
    the raw format in case it sits on top of one of these protocols, but in
    the common case the nested bdrv_getlength() call on the protocol driver
    will use the cache again and avoid an expensive drv->bdrv_getlength()
    call.
    
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Loading