int nbd_client_co_flush(BlockDriverState *bs) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_FLUSH }; struct nbd_reply reply; ssize_t ret; if (!(client->nbdflags & NBD_FLAG_SEND_FLUSH)) { return 0; } if (client->nbdflags & NBD_FLAG_SEND_FUA) { request.type |= NBD_CMD_FLAG_FUA; } request.from = 0; request.len = 0; nbd_coroutine_start(client, &request); ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL, 0); } nbd_coroutine_end(client, &request); return -reply.error; }
int nbd_client_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_TRIM }; struct nbd_reply reply; ssize_t ret; if (!(client->nbdflags & NBD_FLAG_SEND_TRIM)) { return 0; } request.from = sector_num * 512; request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); ret = nbd_co_send_request(bs, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL, 0); } nbd_coroutine_end(client, &request); return -reply.error; }
int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int bytes, BdrvRequestFlags flags) { ssize_t ret; NBDClientSession *client = nbd_get_client_session(bs); NBDRequest request = { .type = NBD_CMD_WRITE_ZEROES, .from = offset, .len = bytes, }; NBDReply reply; if (!(client->nbdflags & NBD_FLAG_SEND_WRITE_ZEROES)) { return -ENOTSUP; } if (flags & BDRV_REQ_FUA) { assert(client->nbdflags & NBD_FLAG_SEND_FUA); request.flags |= NBD_CMD_FLAG_FUA; } if (!(flags & BDRV_REQ_MAY_UNMAP)) { request.flags |= NBD_CMD_FLAG_NO_HOLE; } ret = nbd_co_send_request(bs, &request, NULL); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL); } nbd_coroutine_end(bs, &request); return -reply.error; }
static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_WRITE }; struct nbd_reply reply; ssize_t ret; if (!bdrv_enable_write_cache(bs) && (client->nbdflags & NBD_FLAG_SEND_FUA)) { request.type |= NBD_CMD_FLAG_FUA; } request.from = sector_num * 512; request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); ret = nbd_co_send_request(bs, &request, qiov, offset); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL, 0); } nbd_coroutine_end(client, &request); return -reply.error; }
int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes) { NBDClientSession *client = nbd_get_client_session(bs); NBDRequest request = { .type = NBD_CMD_TRIM, .from = offset, .len = bytes, }; NBDReply reply; ssize_t ret; if (!(client->nbdflags & NBD_FLAG_SEND_TRIM)) { return 0; } ret = nbd_co_send_request(bs, &request, NULL); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL); } nbd_coroutine_end(bs, &request); return -reply.error; }
static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { BDRVNBDState *s = bs->opaque; struct nbd_request request; struct nbd_reply reply; ssize_t ret; if (!(s->nbdflags & NBD_FLAG_SEND_TRIM)) { return 0; } request.type = NBD_CMD_TRIM; request.from = sector_num * 512;; request.len = nb_sectors * 512; nbd_coroutine_start(s, &request); ret = nbd_co_send_request(s, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(s, &request, &reply, NULL, 0); } nbd_coroutine_end(s, &request); return -reply.error; }
int nbd_client_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { NBDClientSession *client = nbd_get_client_session(bs); NBDRequest request = { .type = NBD_CMD_WRITE, .from = offset, .len = bytes, }; NBDReply reply; ssize_t ret; if (flags & BDRV_REQ_FUA) { assert(client->nbdflags & NBD_FLAG_SEND_FUA); request.flags |= NBD_CMD_FLAG_FUA; } assert(bytes <= NBD_MAX_BUFFER_SIZE); ret = nbd_co_send_request(bs, &request, qiov); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, NULL); } nbd_coroutine_end(bs, &request); return -reply.error; }
static int nbd_co_flush(BlockDriverState *bs) { BDRVNBDState *s = bs->opaque; struct nbd_request request; struct nbd_reply reply; ssize_t ret; if (!(s->nbdflags & NBD_FLAG_SEND_FLUSH)) { return 0; } request.type = NBD_CMD_FLUSH; if (s->nbdflags & NBD_FLAG_SEND_FUA) { request.type |= NBD_CMD_FLAG_FUA; } request.from = 0; request.len = 0; nbd_coroutine_start(s, &request); ret = nbd_co_send_request(s, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(s, &request, &reply, NULL, 0); } nbd_coroutine_end(s, &request); return -reply.error; }
static int nbd_co_writev_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { BDRVNBDState *s = bs->opaque; struct nbd_request request; struct nbd_reply reply; ssize_t ret; request.type = NBD_CMD_WRITE; if (!bdrv_enable_write_cache(bs) && (s->nbdflags & NBD_FLAG_SEND_FUA)) { request.type |= NBD_CMD_FLAG_FUA; } request.from = sector_num * 512; request.len = nb_sectors * 512; nbd_coroutine_start(s, &request); ret = nbd_co_send_request(s, &request, qiov->iov, offset); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(s, &request, &reply, NULL, 0); } nbd_coroutine_end(s, &request); return -reply.error; }
int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_READ, .from = offset, .len = bytes, }; struct nbd_reply reply; ssize_t ret; assert(bytes <= NBD_MAX_BUFFER_SIZE); assert(!flags); nbd_coroutine_start(client, &request); ret = nbd_co_send_request(bs, &request, NULL); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, qiov); } nbd_coroutine_end(client, &request); return -reply.error; }
static int nbd_co_request(BlockDriverState *bs, NBDRequest *request, QEMUIOVector *qiov) { NBDClientSession *client = nbd_get_client_session(bs); NBDReply reply; int ret; assert(!qiov || request->type == NBD_CMD_WRITE || request->type == NBD_CMD_READ); ret = nbd_co_send_request(bs, request, request->type == NBD_CMD_WRITE ? qiov : NULL); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, request, &reply, request->type == NBD_CMD_READ ? qiov : NULL); } return -reply.error; }
static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { struct nbd_request request = { .type = NBD_CMD_READ }; struct nbd_reply reply; ssize_t ret; request.from = sector_num * 512; request.len = nb_sectors * 512; nbd_coroutine_start(client, &request); ret = nbd_co_send_request(client, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(client, &request, &reply, qiov, offset); } nbd_coroutine_end(client, &request); return -reply.error; }
static int nbd_co_readv_1(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int offset) { BDRVNBDState *s = bs->opaque; struct nbd_request request; struct nbd_reply reply; ssize_t ret; request.type = NBD_CMD_READ; request.from = sector_num * 512; request.len = nb_sectors * 512; nbd_coroutine_start(s, &request); ret = nbd_co_send_request(s, &request, NULL, 0); if (ret < 0) { reply.error = -ret; } else { nbd_co_receive_reply(s, &request, &reply, qiov->iov, offset); } nbd_coroutine_end(s, &request); return -reply.error; }