void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)

{

    uint32_t type;

    struct iovec *in_iov = req->elem->in_sg;

    struct iovec *iov = req->elem->out_sg;

    unsigned in_num = req->elem->in_num;

    unsigned out_num = req->elem->out_num;



    if (req->elem->out_num < 1 || req->elem->in_num < 1) {

        error_report("virtio-blk missing headers");

        exit(1);

    }



    if (unlikely(iov_to_buf(iov, out_num, 0, &req->out,

                            sizeof(req->out)) != sizeof(req->out))) {

        error_report("virtio-blk request outhdr too short");

        exit(1);

    }



    iov_discard_front(&iov, &out_num, sizeof(req->out));



    if (in_num < 1 ||

        in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {

        error_report("virtio-blk request inhdr too short");

        exit(1);

    }



    req->in = (void *)in_iov[in_num - 1].iov_base

              + in_iov[in_num - 1].iov_len

              - sizeof(struct virtio_blk_inhdr);

    iov_discard_back(in_iov, &in_num, sizeof(struct virtio_blk_inhdr));



    type = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type);



    if (type & VIRTIO_BLK_T_FLUSH) {

        virtio_blk_handle_flush(req, mrb);

    } else if (type & VIRTIO_BLK_T_SCSI_CMD) {

        virtio_blk_handle_scsi(req);

    } else if (type & VIRTIO_BLK_T_GET_ID) {

        VirtIOBlock *s = req->dev;



        /*

         * NB: per existing s/n string convention the string is

         * terminated by '\0' only when shorter than buffer.

         */

        strncpy(req->elem->in_sg[0].iov_base,

                s->blk.serial ? s->blk.serial : "",

                MIN(req->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));

        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);

        virtio_blk_free_request(req);

    } else if (type & VIRTIO_BLK_T_OUT) {

        qemu_iovec_init_external(&req->qiov, &req->elem->out_sg[1],

                                 req->elem->out_num - 1);

        virtio_blk_handle_write(req, mrb);

    } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) {

        /* VIRTIO_BLK_T_IN is 0, so we can't just & it. */

        qemu_iovec_init_external(&req->qiov, &req->elem->in_sg[0],

                                 req->elem->in_num - 1);

        virtio_blk_handle_read(req);

    } else {

        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);

        virtio_blk_free_request(req);

    }

}

void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)

{

    uint32_t type;

    struct iovec *in_iov = req->elem->in_sg;

    struct iovec *iov = req->elem->out_sg;

    unsigned in_num = req->elem->in_num;

    unsigned out_num = req->elem->out_num;



    if (req->elem->out_num < 1 || req->elem->in_num < 1) {

        error_report("virtio-blk missing headers");

        exit(1);

    }



    if (unlikely(iov_to_buf(iov, out_num, 0, &req->out,

                            sizeof(req->out)) != sizeof(req->out))) {

        error_report("virtio-blk request outhdr too short");

        exit(1);

    }



    iov_discard_front(&iov, &out_num, sizeof(req->out));



    if (in_num < 1 ||

        in_iov[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {

        error_report("virtio-blk request inhdr too short");

        exit(1);

    }



    req->in = (void *)in_iov[in_num - 1].iov_base

              + in_iov[in_num - 1].iov_len

              - sizeof(struct virtio_blk_inhdr);

    iov_discard_back(in_iov, &in_num, sizeof(struct virtio_blk_inhdr));



    type = virtio_ldl_p(VIRTIO_DEVICE(req->dev), &req->out.type);



    if (type & VIRTIO_BLK_T_FLUSH) {

        virtio_blk_handle_flush(req, mrb);

    } else if (type & VIRTIO_BLK_T_SCSI_CMD) {

        virtio_blk_handle_scsi(req);

    } else if (type & VIRTIO_BLK_T_GET_ID) {

        VirtIOBlock *s = req->dev;



        







        strncpy(req->elem->in_sg[0].iov_base,

                s->blk.serial ? s->blk.serial : "",

                MIN(req->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));

        virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);

        virtio_blk_free_request(req);

    } else if (type & VIRTIO_BLK_T_OUT) {

        qemu_iovec_init_external(&req->qiov, &req->elem->out_sg[1],

                                 req->elem->out_num - 1);

        virtio_blk_handle_write(req, mrb);

    } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) {

        

        qemu_iovec_init_external(&req->qiov, &req->elem->in_sg[0],

                                 req->elem->in_num - 1);

        virtio_blk_handle_read(req);

    } else {

        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);

        virtio_blk_free_request(req);

    }

}

    struct iovec *in_iov = req->elem->in_sg;     struct iovec *iov = req->elem->out_sg;     unsigned in_num = req->elem->in_num;     unsigned out_num = req->elem->out_num;     if (req->elem->out_num < 1 || req->elem->in_num < 1) {         strncpy(req->elem->in_sg[0].iov_base,                 MIN(req->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));         qemu_iovec_init_external(&req->qiov, &req->elem->out_sg[1],                                  req->elem->out_num - 1);         qemu_iovec_init_external(&req->qiov, &req->elem->in_sg[0],                                  req->elem->in_num - 1);
void FUNC_0(VirtIOBlockReq *VAR_0, MultiReqBuffer *VAR_1)

{

    uint32_t type;

    struct iovec *VAR_2 = VAR_0->elem->in_sg;

    struct iovec *VAR_3 = VAR_0->elem->out_sg;

    unsigned VAR_4 = VAR_0->elem->VAR_4;

    unsigned VAR_5 = VAR_0->elem->VAR_5;



    if (VAR_0->elem->VAR_5 < 1 || VAR_0->elem->VAR_4 < 1) {

        error_report("virtio-blk missing headers");

        exit(1);

    }



    if (unlikely(iov_to_buf(VAR_3, VAR_5, 0, &VAR_0->out,

                            sizeof(VAR_0->out)) != sizeof(VAR_0->out))) {

        error_report("virtio-blk request outhdr too short");

        exit(1);

    }



    iov_discard_front(&VAR_3, &VAR_5, sizeof(VAR_0->out));



    if (VAR_4 < 1 ||

        VAR_2[VAR_4 - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {

        error_report("virtio-blk request inhdr too short");

        exit(1);

    }



    VAR_0->in = (void *)VAR_2[VAR_4 - 1].iov_base

              + VAR_2[VAR_4 - 1].iov_len

              - sizeof(struct virtio_blk_inhdr);

    iov_discard_back(VAR_2, &VAR_4, sizeof(struct virtio_blk_inhdr));



    type = virtio_ldl_p(VIRTIO_DEVICE(VAR_0->dev), &VAR_0->out.type);



    if (type & VIRTIO_BLK_T_FLUSH) {

        virtio_blk_handle_flush(VAR_0, VAR_1);

    } else if (type & VIRTIO_BLK_T_SCSI_CMD) {

        virtio_blk_handle_scsi(VAR_0);

    } else if (type & VIRTIO_BLK_T_GET_ID) {

        VirtIOBlock *s = VAR_0->dev;



        







        strncpy(VAR_0->elem->in_sg[0].iov_base,

                s->blk.serial ? s->blk.serial : "",

                MIN(VAR_0->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));

        virtio_blk_req_complete(VAR_0, VIRTIO_BLK_S_OK);

        virtio_blk_free_request(VAR_0);

    } else if (type & VIRTIO_BLK_T_OUT) {

        qemu_iovec_init_external(&VAR_0->qiov, &VAR_0->elem->out_sg[1],

                                 VAR_0->elem->VAR_5 - 1);

        virtio_blk_handle_write(VAR_0, VAR_1);

    } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) {

        

        qemu_iovec_init_external(&VAR_0->qiov, &VAR_0->elem->in_sg[0],

                                 VAR_0->elem->VAR_4 - 1);

        virtio_blk_handle_read(VAR_0);

    } else {

        virtio_blk_req_complete(VAR_0, VIRTIO_BLK_S_UNSUPP);

        virtio_blk_free_request(VAR_0);

    }

}

void FUNC_0(VirtIOBlockReq *VAR_0, MultiReqBuffer *VAR_1)
{ uint32_t type; struct iovec *VAR_2 = VAR_0->elem->in_sg; struct iovec *VAR_3 = VAR_0->elem->out_sg; unsigned VAR_4 = VAR_0->elem->VAR_4; unsigned VAR_5 = VAR_0->elem->VAR_5; if (VAR_0->elem->VAR_5 < 1 || VAR_0->elem->VAR_4 < 1) { error_report("virtio-blk missing headers"); exit(1); } if (unlikely(iov_to_buf(VAR_3, VAR_5, 0, &VAR_0->out,
sizeof(VAR_0->out)) != sizeof(VAR_0->out))) { error_report("virtio-blk request outhdr too short"); exit(1); } iov_discard_front(&VAR_3, &VAR_5, sizeof(VAR_0->out)); if (VAR_4 < 1 ||
VAR_2[VAR_4 - 1].iov_len < sizeof(struct virtio_blk_inhdr)) { error_report("virtio-blk request inhdr too short"); exit(1); } VAR_0->in = (void *)VAR_2[VAR_4 - 1].iov_base
+ VAR_2[VAR_4 - 1].iov_len
- sizeof(struct virtio_blk_inhdr); iov_discard_back(VAR_2, &VAR_4, sizeof(struct virtio_blk_inhdr)); type = virtio_ldl_p(VIRTIO_DEVICE(VAR_0->dev), &VAR_0->out.type); if (type & VIRTIO_BLK_T_FLUSH) { virtio_blk_handle_flush(VAR_0, VAR_1); } else if (type & VIRTIO_BLK_T_SCSI_CMD) { virtio_blk_handle_scsi(VAR_0); } else if (type & VIRTIO_BLK_T_GET_ID) { VirtIOBlock *s = VAR_0->dev; strncpy(VAR_0->elem->in_sg[0].iov_base,
s->blk.serial ? s->blk.serial : "",
MIN(VAR_0->elem->in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES)); virtio_blk_req_complete(VAR_0, VIRTIO_BLK_S_OK); virtio_blk_free_request(VAR_0); } else if (type & VIRTIO_BLK_T_OUT) { qemu_iovec_init_external(&VAR_0->qiov, &VAR_0->elem->out_sg[1],
VAR_0->elem->VAR_5 - 1); virtio_blk_handle_write(VAR_0, VAR_1); } else if (type == VIRTIO_BLK_T_IN || type == VIRTIO_BLK_T_BARRIER) { qemu_iovec_init_external(&VAR_0->qiov, &VAR_0->elem->in_sg[0],
VAR_0->elem->VAR_4 - 1); virtio_blk_handle_read(VAR_0); } else { virtio_blk_req_complete(VAR_0, VIRTIO_BLK_S_UNSUPP); virtio_blk_free_request(VAR_0); } }