/* nbd_receive_reply * Returns 1 on success * 0 on eof, when no data was read (errp is not set) * negative errno on failure (errp is set) */ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp) { int ret; const char *type; ret = nbd_read_eof(ioc, &reply->magic, sizeof(reply->magic), errp); if (ret <= 0) { return ret; } be32_to_cpus(&reply->magic); switch (reply->magic) { case NBD_SIMPLE_REPLY_MAGIC: ret = nbd_receive_simple_reply(ioc, &reply->simple, errp); if (ret < 0) { break; } trace_nbd_receive_simple_reply(reply->simple.error, nbd_err_lookup(reply->simple.error), reply->handle); break; case NBD_STRUCTURED_REPLY_MAGIC: ret = nbd_receive_structured_reply_chunk(ioc, &reply->structured, errp); if (ret < 0) { break; } type = nbd_reply_type_lookup(reply->structured.type); trace_nbd_receive_structured_reply_chunk(reply->structured.flags, reply->structured.type, type, reply->structured.handle, reply->structured.length); break; default: error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", reply->magic); return -EINVAL; } if (ret < 0) { return ret; } return 1; }
/* nbd_receive_reply * Returns 1 on success * 0 on eof, when no data was read (errp is not set) * negative errno on failure (errp is set) */ int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp) { uint8_t buf[NBD_REPLY_SIZE]; uint32_t magic; int ret; ret = nbd_read_eof(ioc, buf, sizeof(buf), errp); if (ret <= 0) { return ret; } /* Reply [ 0 .. 3] magic (NBD_REPLY_MAGIC) [ 4 .. 7] error (0 == no error) [ 7 .. 15] handle */ magic = ldl_be_p(buf); reply->error = ldl_be_p(buf + 4); reply->handle = ldq_be_p(buf + 8); reply->error = nbd_errno_to_system_errno(reply->error); if (reply->error == ESHUTDOWN) { /* This works even on mingw which lacks a native ESHUTDOWN */ error_setg(errp, "server shutting down"); return -EINVAL; } trace_nbd_receive_reply(magic, reply->error, reply->handle); if (magic != NBD_REPLY_MAGIC) { error_setg(errp, "invalid magic (got 0x%" PRIx32 ")", magic); return -EINVAL; } return 1; }