static coroutine_fn void nbd_trip(void *opaque)

{

    NBDClient *client = opaque;

    NBDExport *exp = client->exp;

    NBDRequestData *req;

    NBDRequest request = { 0 };    /* GCC thinks it can be used uninitialized */

    int ret;

    int flags;

    int reply_data_len = 0;

    Error *local_err = NULL;

    char *msg = NULL;



    trace_nbd_trip();

    if (client->closing) {

        nbd_client_put(client);

        return;

    }



    req = nbd_request_get(client);

    ret = nbd_co_receive_request(req, &request, &local_err);

    client->recv_coroutine = NULL;

    nbd_client_receive_next_request(client);

    if (ret == -EIO) {

        goto disconnect;

    }



    if (ret < 0) {

        goto reply;

    }



    if (client->closing) {

        /*

         * The client may be closed when we are blocked in

         * nbd_co_receive_request()

         */

        goto done;

    }



    switch (request.type) {

    case NBD_CMD_READ:

        /* XXX: NBD Protocol only documents use of FUA with WRITE */

        if (request.flags & NBD_CMD_FLAG_FUA) {

            ret = blk_co_flush(exp->blk);

            if (ret < 0) {

                error_setg_errno(&local_err, -ret, "flush failed");

                break;

            }

        }



        ret = blk_pread(exp->blk, request.from + exp->dev_offset,

                        req->data, request.len);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "reading from file failed");

            break;

        }



        reply_data_len = request.len;



        break;

    case NBD_CMD_WRITE:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            ret = -EROFS;

            break;

        }



        flags = 0;

        if (request.flags & NBD_CMD_FLAG_FUA) {

            flags |= BDRV_REQ_FUA;

        }

        ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,

                         req->data, request.len, flags);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "writing to file failed");

        }



        break;

    case NBD_CMD_WRITE_ZEROES:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            ret = -EROFS;

            break;

        }



        flags = 0;

        if (request.flags & NBD_CMD_FLAG_FUA) {

            flags |= BDRV_REQ_FUA;

        }

        if (!(request.flags & NBD_CMD_FLAG_NO_HOLE)) {

            flags |= BDRV_REQ_MAY_UNMAP;

        }

        ret = blk_pwrite_zeroes(exp->blk, request.from + exp->dev_offset,

                                request.len, flags);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "writing to file failed");

        }



        break;

    case NBD_CMD_DISC:

        /* unreachable, thanks to special case in nbd_co_receive_request() */

        abort();



    case NBD_CMD_FLUSH:

        ret = blk_co_flush(exp->blk);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "flush failed");

        }



        break;

    case NBD_CMD_TRIM:

        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,

                              request.len);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "discard failed");

        }



        break;

    default:

        error_setg(&local_err, "invalid request type (%" PRIu32 ") received",

                   request.type);

        ret = -EINVAL;

    }



reply:

    if (local_err) {

        /* If we get here, local_err was not a fatal error, and should be sent

         * to the client. */

        assert(ret < 0);

        msg = g_strdup(error_get_pretty(local_err));

        error_report_err(local_err);

        local_err = NULL;

    }



    if (client->structured_reply &&

        (ret < 0 || request.type == NBD_CMD_READ)) {

        if (ret < 0) {

            ret = nbd_co_send_structured_error(req->client, request.handle,

                                               -ret, msg, &local_err);

        } else {

            ret = nbd_co_send_structured_read(req->client, request.handle,

                                              request.from, req->data,

                                              reply_data_len, &local_err);

        }

    } else {

        ret = nbd_co_send_simple_reply(req->client, request.handle,

                                       ret < 0 ? -ret : 0,

                                       req->data, reply_data_len, &local_err);

    }

    g_free(msg);

    if (ret < 0) {

        error_prepend(&local_err, "Failed to send reply: ");

        goto disconnect;

    }



    /* We must disconnect after NBD_CMD_WRITE if we did not

     * read the payload.

     */

    if (!req->complete) {

        error_setg(&local_err, "Request handling failed in intermediate state");

        goto disconnect;

    }



done:

    nbd_request_put(req);

    nbd_client_put(client);

    return;



disconnect:

    if (local_err) {

        error_reportf_err(local_err, "Disconnect client, due to: ");

    }

    nbd_request_put(req);

    client_close(client, true);

    nbd_client_put(client);

}

static coroutine_fn void nbd_trip(void *opaque)

{

    NBDClient *client = opaque;

    NBDExport *exp = client->exp;

    NBDRequestData *req;

    NBDRequest request = { 0 };    

    int ret;

    int flags;

    int reply_data_len = 0;

    Error *local_err = NULL;

    char *msg = NULL;



    trace_nbd_trip();

    if (client->closing) {

        nbd_client_put(client);

        return;

    }



    req = nbd_request_get(client);

    ret = nbd_co_receive_request(req, &request, &local_err);

    client->recv_coroutine = NULL;

    nbd_client_receive_next_request(client);

    if (ret == -EIO) {

        goto disconnect;

    }



    if (ret < 0) {

        goto reply;

    }



    if (client->closing) {

        







        goto done;

    }



    switch (request.type) {

    case NBD_CMD_READ:

        

        if (request.flags & NBD_CMD_FLAG_FUA) {

            ret = blk_co_flush(exp->blk);

            if (ret < 0) {

                error_setg_errno(&local_err, -ret, "flush failed");

                break;

            }

        }



        ret = blk_pread(exp->blk, request.from + exp->dev_offset,

                        req->data, request.len);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "reading from file failed");

            break;

        }



        reply_data_len = request.len;



        break;

    case NBD_CMD_WRITE:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            ret = -EROFS;

            break;

        }



        flags = 0;

        if (request.flags & NBD_CMD_FLAG_FUA) {

            flags |= BDRV_REQ_FUA;

        }

        ret = blk_pwrite(exp->blk, request.from + exp->dev_offset,

                         req->data, request.len, flags);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "writing to file failed");

        }



        break;

    case NBD_CMD_WRITE_ZEROES:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            ret = -EROFS;

            break;

        }



        flags = 0;

        if (request.flags & NBD_CMD_FLAG_FUA) {

            flags |= BDRV_REQ_FUA;

        }

        if (!(request.flags & NBD_CMD_FLAG_NO_HOLE)) {

            flags |= BDRV_REQ_MAY_UNMAP;

        }

        ret = blk_pwrite_zeroes(exp->blk, request.from + exp->dev_offset,

                                request.len, flags);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "writing to file failed");

        }



        break;

    case NBD_CMD_DISC:

        

        abort();



    case NBD_CMD_FLUSH:

        ret = blk_co_flush(exp->blk);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "flush failed");

        }



        break;

    case NBD_CMD_TRIM:

        ret = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,

                              request.len);

        if (ret < 0) {

            error_setg_errno(&local_err, -ret, "discard failed");

        }



        break;

    default:

        error_setg(&local_err, "invalid request type (%" PRIu32 ") received",

                   request.type);

        ret = -EINVAL;

    }



reply:

    if (local_err) {

        



        assert(ret < 0);

        msg = g_strdup(error_get_pretty(local_err));

        error_report_err(local_err);

        local_err = NULL;

    }



    if (client->structured_reply &&

        (ret < 0 || request.type == NBD_CMD_READ)) {

        if (ret < 0) {

            ret = nbd_co_send_structured_error(req->client, request.handle,

                                               -ret, msg, &local_err);

        } else {

            ret = nbd_co_send_structured_read(req->client, request.handle,

                                              request.from, req->data,

                                              reply_data_len, &local_err);

        }

    } else {

        ret = nbd_co_send_simple_reply(req->client, request.handle,

                                       ret < 0 ? -ret : 0,

                                       req->data, reply_data_len, &local_err);

    }

    g_free(msg);

    if (ret < 0) {

        error_prepend(&local_err, "Failed to send reply: ");

        goto disconnect;

    }



    





    if (!req->complete) {

        error_setg(&local_err, "Request handling failed in intermediate state");

        goto disconnect;

    }



done:

    nbd_request_put(req);

    nbd_client_put(client);

    return;



disconnect:

    if (local_err) {

        error_reportf_err(local_err, "Disconnect client, due to: ");

    }

    nbd_request_put(req);

    client_close(client, true);

    nbd_client_put(client);

}

        } else {
static coroutine_fn void FUNC_0(void *opaque)

{

    NBDClient *client = opaque;

    NBDExport *exp = client->exp;

    NBDRequestData *req;

    NBDRequest request = { 0 };    

    int VAR_0;

    int VAR_1;

    int VAR_2 = 0;

    Error *local_err = NULL;

    char *VAR_3 = NULL;



    trace_nbd_trip();

    if (client->closing) {

        nbd_client_put(client);

        return;

    }



    req = nbd_request_get(client);

    VAR_0 = nbd_co_receive_request(req, &request, &local_err);

    client->recv_coroutine = NULL;

    nbd_client_receive_next_request(client);

    if (VAR_0 == -EIO) {

        goto disconnect;

    }



    if (VAR_0 < 0) {

        goto reply;

    }



    if (client->closing) {

        







        goto done;

    }



    switch (request.type) {

    case NBD_CMD_READ:

        

        if (request.VAR_1 & NBD_CMD_FLAG_FUA) {

            VAR_0 = blk_co_flush(exp->blk);

            if (VAR_0 < 0) {

                error_setg_errno(&local_err, -VAR_0, "flush failed");

                break;

            }

        }



        VAR_0 = blk_pread(exp->blk, request.from + exp->dev_offset,

                        req->data, request.len);

        if (VAR_0 < 0) {

            error_setg_errno(&local_err, -VAR_0, "reading from file failed");

            break;

        }



        VAR_2 = request.len;



        break;

    case NBD_CMD_WRITE:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            VAR_0 = -EROFS;

            break;

        }



        VAR_1 = 0;

        if (request.VAR_1 & NBD_CMD_FLAG_FUA) {

            VAR_1 |= BDRV_REQ_FUA;

        }

        VAR_0 = blk_pwrite(exp->blk, request.from + exp->dev_offset,

                         req->data, request.len, VAR_1);

        if (VAR_0 < 0) {

            error_setg_errno(&local_err, -VAR_0, "writing to file failed");

        }



        break;

    case NBD_CMD_WRITE_ZEROES:

        if (exp->nbdflags & NBD_FLAG_READ_ONLY) {

            error_setg(&local_err, "Export is read-only");

            VAR_0 = -EROFS;

            break;

        }



        VAR_1 = 0;

        if (request.VAR_1 & NBD_CMD_FLAG_FUA) {

            VAR_1 |= BDRV_REQ_FUA;

        }

        if (!(request.VAR_1 & NBD_CMD_FLAG_NO_HOLE)) {

            VAR_1 |= BDRV_REQ_MAY_UNMAP;

        }

        VAR_0 = blk_pwrite_zeroes(exp->blk, request.from + exp->dev_offset,

                                request.len, VAR_1);

        if (VAR_0 < 0) {

            error_setg_errno(&local_err, -VAR_0, "writing to file failed");

        }



        break;

    case NBD_CMD_DISC:

        

        abort();



    case NBD_CMD_FLUSH:

        VAR_0 = blk_co_flush(exp->blk);

        if (VAR_0 < 0) {

            error_setg_errno(&local_err, -VAR_0, "flush failed");

        }



        break;

    case NBD_CMD_TRIM:

        VAR_0 = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,

                              request.len);

        if (VAR_0 < 0) {

            error_setg_errno(&local_err, -VAR_0, "discard failed");

        }



        break;

    default:

        error_setg(&local_err, "invalid request type (%" PRIu32 ") received",

                   request.type);

        VAR_0 = -EINVAL;

    }



reply:

    if (local_err) {

        



        assert(VAR_0 < 0);

        VAR_3 = g_strdup(error_get_pretty(local_err));

        error_report_err(local_err);

        local_err = NULL;

    }



    if (client->structured_reply &&

        (VAR_0 < 0 || request.type == NBD_CMD_READ)) {

        if (VAR_0 < 0) {

            VAR_0 = nbd_co_send_structured_error(req->client, request.handle,

                                               -VAR_0, VAR_3, &local_err);

        } else {

            VAR_0 = nbd_co_send_structured_read(req->client, request.handle,

                                              request.from, req->data,

                                              VAR_2, &local_err);

        }

    } else {

        VAR_0 = nbd_co_send_simple_reply(req->client, request.handle,

                                       VAR_0 < 0 ? -VAR_0 : 0,

                                       req->data, VAR_2, &local_err);

    }

    g_free(VAR_3);

    if (VAR_0 < 0) {

        error_prepend(&local_err, "Failed to send reply: ");

        goto disconnect;

    }



    





    if (!req->complete) {

        error_setg(&local_err, "Request handling failed in intermediate state");

        goto disconnect;

    }



done:

    nbd_request_put(req);

    nbd_client_put(client);

    return;



disconnect:

    if (local_err) {

        error_reportf_err(local_err, "Disconnect client, due to: ");

    }

    nbd_request_put(req);

    client_close(client, true);

    nbd_client_put(client);

}

static coroutine_fn void FUNC_0(void *opaque)
{ NBDClient *client = opaque; NBDExport *exp = client->exp; NBDRequestData *req; NBDRequest request = { 0 }; int VAR_0; int VAR_1; int VAR_2 = 0; Error *local_err = NULL; char *VAR_3 = NULL; trace_nbd_trip(); if (client->closing) { nbd_client_put(client); return; } req = nbd_request_get(client); VAR_0 = nbd_co_receive_request(req, &request, &local_err); client->recv_coroutine = NULL; nbd_client_receive_next_request(client); if (VAR_0 == -EIO) { goto disconnect; } if (VAR_0 < 0) { goto reply; } if (client->closing) { goto done; } switch (request.type) { case NBD_CMD_READ:
if (request.VAR_1 & NBD_CMD_FLAG_FUA) { VAR_0 = blk_co_flush(exp->blk); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "flush failed"); break; } } VAR_0 = blk_pread(exp->blk, request.from + exp->dev_offset,
req->data, request.len); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "reading from file failed"); break; } VAR_2 = request.len; break; case NBD_CMD_WRITE:
if (exp->nbdflags & NBD_FLAG_READ_ONLY) { error_setg(&local_err, "Export is read-only"); VAR_0 = -EROFS; break; } VAR_1 = 0; if (request.VAR_1 & NBD_CMD_FLAG_FUA) { VAR_1 |= BDRV_REQ_FUA; } VAR_0 = blk_pwrite(exp->blk, request.from + exp->dev_offset,
req->data, request.len, VAR_1); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "writing to file failed"); } break; case NBD_CMD_WRITE_ZEROES:
if (exp->nbdflags & NBD_FLAG_READ_ONLY) { error_setg(&local_err, "Export is read-only"); VAR_0 = -EROFS; break; } VAR_1 = 0; if (request.VAR_1 & NBD_CMD_FLAG_FUA) { VAR_1 |= BDRV_REQ_FUA; } if (!(request.VAR_1 & NBD_CMD_FLAG_NO_HOLE)) { VAR_1 |= BDRV_REQ_MAY_UNMAP; } VAR_0 = blk_pwrite_zeroes(exp->blk, request.from + exp->dev_offset,
request.len, VAR_1); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "writing to file failed"); } break; case NBD_CMD_DISC:
abort(); case NBD_CMD_FLUSH:
VAR_0 = blk_co_flush(exp->blk); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "flush failed"); } break; case NBD_CMD_TRIM:
VAR_0 = blk_co_pdiscard(exp->blk, request.from + exp->dev_offset,
request.len); if (VAR_0 < 0) { error_setg_errno(&local_err, -VAR_0, "discard failed"); } break; default:
error_setg(&local_err, "invalid request type (%" PRIu32 ") received",
request.type); VAR_0 = -EINVAL; } reply:
if (local_err) { assert(VAR_0 < 0); VAR_3 = g_strdup(error_get_pretty(local_err)); error_report_err(local_err); local_err = NULL; } if (client->structured_reply &&
(VAR_0 < 0 || request.type == NBD_CMD_READ)) { if (VAR_0 < 0) { VAR_0 = nbd_co_send_structured_error(req->client, request.handle,
-VAR_0, VAR_3, &local_err); } else { VAR_0 = nbd_co_send_structured_read(req->client, request.handle,
request.from, req->data,
VAR_2, &local_err); } } else { VAR_0 = nbd_co_send_simple_reply(req->client, request.handle,
VAR_0 < 0 ? -VAR_0 : 0,
req->data, VAR_2, &local_err); } g_free(VAR_3); if (VAR_0 < 0) { error_prepend(&local_err, "Failed to send reply: "); goto disconnect; } if (!req->complete) { error_setg(&local_err, "Request handling failed in intermediate state"); goto disconnect; } done:
nbd_request_put(req); nbd_client_put(client); return; disconnect:
if (local_err) { error_reportf_err(local_err, "Disconnect client, due to: "); } nbd_request_put(req); client_close(client, true); nbd_client_put(client); }