• Mike Christie's avatar
    vhost-scsi: Fix alignment handling with windows · 5ced58bf
    Mike Christie authored
    The linux block layer requires bios/requests to have lengths with a 512
    byte alignment. Some drivers/layers like dm-crypt and the directi IO code
    will test for it and just fail. Other drivers like SCSI just assume the
    requirement is met and will end up in infinte retry loops. The problem
    for drivers like SCSI is that it uses functions like blk_rq_cur_sectors
    and blk_rq_sectors which divide the request's length by 512. If there's
    lefovers then it just gets dropped. But other code in the block/scsi
    layer may use blk_rq_bytes/blk_rq_cur_bytes and end up thinking there is
    still data left and try to retry the cmd. We can then end up getting
    stuck in retry loops where part of the block/scsi thinks there is data
    left, but other parts think we want to do IOs of zero length.
    
    Linux will always check for alignment, but windows will not. When
    vhost-scsi then translates the iovec it gets from a windows guest to a
    scatterlist, we can end up with sg items where the sg->length is not
    divisible by 512 due to the misaligned offset:
    
    sg[0].offset = 255;
    sg[0].length = 3841;
    sg...
    sg[N].offset = 0;
    sg[N].length = 255;
    
    When the lio backends then convert the SG to bios or other iovecs, we
    end up sending them with the same misaligned values and can hit the
    issues above.
    
    This just has us drop down to allocating a temp page and copying the data
    when we detect a misaligned buffer and the IO is large enough that it
    will get split into multiple bad IOs.
    Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
    Message-Id: <20230709202859.138387-2-michael.christie@oracle.com>
    Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
    Acked-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    5ced58bf
scsi.c 67.5 KB