static int nbd_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { BDRVNBDState *s = bs->opaque; struct nbd_request request; struct nbd_reply reply; request.type = NBD_CMD_WRITE; request.handle = (uint64_t)(intptr_t)bs; request.from = sector_num * 512;; request.len = nb_sectors * 512; if (nbd_send_request(s->sock, &request) == -1) return -errno; if (nbd_wr_sync(s->sock, (uint8_t*)buf, request.len, 0) != request.len) return -EIO; if (nbd_receive_reply(s->sock, &reply) == -1) return -errno; if (reply.error !=0) return -reply.error; if (reply.handle != request.handle) return -EIO; return 0; }
static ssize_t write_sync(int fd, void *buffer, size_t size) { int ret; do { /* For writes, we do expect the socket to be writable. */ ret = nbd_wr_sync(fd, buffer, size, false); } while (ret == -EAGAIN); return ret; }
static ssize_t read_sync(int fd, void *buffer, size_t size) { /* Sockets are kept in blocking mode in the negotiation phase. After * that, a non-readable socket simply means that another thread stole * our request/reply. Synchronization is done with recv_coroutine, so * that this is coroutine-safe. */ return nbd_wr_sync(fd, buffer, size, true); }