diff mbox

[06/11] ndctl: fix vendor command residue handling

Message ID 20150905013148.28464.90056.stgit@dwillia2-desk3.amr.corp.intel.com (mailing list archive)
State Accepted
Commit 1df987a1bd9b
Headers show

Commit Message

Dan Williams Sept. 5, 2015, 1:31 a.m. UTC
It is not necessarily an error if the platform returns less than the
requested number of bytes in the output buffer.  Arrange for do_cmd() to
populate the output buffer with all known valid data and update
ndctl_cmd_vendor_get_output_size() to properly handle the case of
positive cmd->status.

Reported-by: Nicholas Moulin <nicholas.w.moulin@linux.intel.com>
Tested-by: Nicholas Moulin <nicholas.w.moulin@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 lib/libndctl.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/lib/libndctl.c b/lib/libndctl.c
index 0b558df46893..be7d7678c3b6 100644
--- a/lib/libndctl.c
+++ b/lib/libndctl.c
@@ -1954,11 +1954,15 @@  NDCTL_EXPORT ssize_t ndctl_cmd_vendor_set_input(struct ndctl_cmd *cmd,
 
 NDCTL_EXPORT ssize_t ndctl_cmd_vendor_get_output_size(struct ndctl_cmd *cmd)
 {
-	if (cmd->type != ND_CMD_VENDOR || cmd->status > 0)
+	if (cmd->type != ND_CMD_VENDOR)
 		return -EINVAL;
-	if (cmd->status < 0)
+	/*
+	 * When cmd->status is non-zero it contains either a negative
+	 * error code, or the number of bytes that are available in the
+	 * output buffer.
+	 */
+	if (cmd->status)
 		return cmd->status;
-
 	return to_vendor_tail(cmd)->out_length;
 }
 
@@ -2297,14 +2301,14 @@  static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 					iter->max_xfer);
 		*(cmd->iter.offset) = offset;
 		rc = ioctl(fd, ioctl_cmd, cmd->cmd_buf);
-		if (rc)
+		if (rc < 0)
 			break;
 
 		if (iter->dir == READ)
 			memcpy(iter->total_buf + offset, iter->data,
-					iter->max_xfer);
-		if (*(cmd->firmware_status)) {
-			rc = iter->total_xfer - offset;
+					iter->max_xfer - rc);
+		if (*(cmd->firmware_status) || rc) {
+			rc = offset + iter->max_xfer - rc;
 			break;
 		}
 	}