We want to allow the block_status callback to be able to report a full
range of errno values, rather than the limited set of NBD_E* defined
in the protocol. To do so, we need to convert from wire error values
back into local errno values at a sooner point in the state machine.
This also changes a structured reply that includes more than one error
designation (theoretically possible at least for structured reads that
uses NBD_REPLY_TYPE_ERROR_OFFSET more than once to NBD_CMD_READ - even
if no existing NBD server actually does that) to preserve the first
error encountered, as that is often more interesting than any
follow-on errors.
---
generator/states-reply-simple.c | 2 +-
generator/states-reply-structured.c | 4 +++-
lib/aio.c | 1 -
lib/internal.h | 2 +-
4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/generator/states-reply-simple.c b/generator/states-reply-simple.c
index e170482..7e5340c 100644
--- a/generator/states-reply-simple.c
+++ b/generator/states-reply-simple.c
@@ -45,7 +45,7 @@
return 0;
}
- cmd->error = error;
+ cmd->error = nbd_internal_errno_of_nbd_error (error);
if (cmd->error == 0 && cmd->type == NBD_CMD_READ) {
h->rbuf = cmd->data;
h->rlen = cmd->count;
diff --git a/generator/states-reply-structured.c b/generator/states-reply-structured.c
index c835713..c7ba892 100644
--- a/generator/states-reply-structured.c
+++ b/generator/states-reply-structured.c
@@ -179,7 +179,9 @@
}
assert (cmd); /* guaranteed by CHECK */
- cmd->error = error;
+ /* Preserve first error encountered */
+ if (cmd->error == 0)
+ cmd->error = nbd_internal_errno_of_nbd_error (error);
if (flags & NBD_REPLY_FLAG_DONE)
SET_NEXT_STATE (%^FINISH_COMMAND);
diff --git a/lib/aio.c b/lib/aio.c
index a129af2..8361854 100644
--- a/lib/aio.c
+++ b/lib/aio.c
@@ -165,7 +165,6 @@ nbd_unlocked_aio_command_completed (struct nbd_handle *h,
return 1;
/* The command failed, set an error indication and return an error. */
- error = nbd_internal_errno_of_nbd_error (error);
set_error (error, "%s: command failed: %s",
nbd_internal_name_of_nbd_cmd (type), strerror (error));
return -1;
diff --git a/lib/internal.h b/lib/internal.h
index c1a57ac..45fc6df 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -223,7 +223,7 @@ struct command_in_flight {
uint32_t count;
void *data; /* Buffer for read/write, opaque for block status */
extent_fn extent_fn;
- uint32_t error;
+ uint32_t error; /* Local errno value */
};
/* crypto.c */
--
2.20.1