[PATCH v3 1/2] scsi: Add iovec support

Bart Van Assche bart.vanassche at sandisk.com
Fri Feb 6 12:36:26 UTC 2015


Changes:
- Add support for decoding iovecs passed via the SG I/O v3 interface.
- Decode the "data in" and "data out" buffers in hex instead of in ASCII.
- Make print_sg_io_buffer() print square brackets instead of its caller.
- Improve consistency with other decoding functions by passing pointers
  to client memory as integers instead of pointers.
- Only print that part of the data in buffer that has been initialized
  by the SCSI LLD driver.

Signed-off-by: Bart Van Assche <bart.vanassche at sandisk.com>
---
 scsi.c | 60 +++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 39 insertions(+), 21 deletions(-)

diff --git a/scsi.c b/scsi.c
index daf7252..bce149e 100644
--- a/scsi.c
+++ b/scsi.c
@@ -36,26 +36,31 @@
 #include "xlat/sg_io_dxfer_direction.h"
 
 static void
-print_sg_io_buffer(struct tcb *tcp, unsigned char *addr, const unsigned int len)
+print_sg_io_buffer(struct tcb *tcp, unsigned long addr, const unsigned int len)
 {
 	unsigned char *buf = NULL;
 	unsigned int allocated, i;
 
+	tprints("[");
 	if (len == 0)
-		return;
+		goto out;
 	allocated = (len > max_strlen) ? max_strlen : len;
 	if ((buf = malloc(allocated)) == NULL ||
-	    umoven(tcp, (unsigned long) addr, allocated, (char *) buf) < 0) {
-		tprintf("%p", addr);
-		free(buf);
-		return;
+	    umoven(tcp, addr, allocated, (char *) buf) < 0) {
+		tprintf("%#lx", addr);
+		goto free;
 	}
 	tprintf("%02x", buf[0]);
 	for (i = 1; i < allocated; ++i)
 		tprintf(", %02x", buf[i]);
-	free(buf);
 	if (allocated != len)
 		tprints(", ...");
+
+free:
+	free(buf);
+
+out:
+	tprints("]");
 }
 
 static void
@@ -64,9 +69,9 @@ print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
 	tprintf("{'%c', ", sg_io->interface_id);
 	printxval(sg_io_dxfer_direction, sg_io->dxfer_direction,
 		  "SG_DXFER_???");
-	tprintf(", cmd[%u]=[", sg_io->cmd_len);
-	print_sg_io_buffer(tcp, sg_io->cmdp, sg_io->cmd_len);
-	tprintf("], mx_sb_len=%d, ", sg_io->mx_sb_len);
+	tprintf(", cmd[%u]=", sg_io->cmd_len);
+	print_sg_io_buffer(tcp, (unsigned long)sg_io->cmdp, sg_io->cmd_len);
+	tprintf(", mx_sb_len=%d, ", sg_io->mx_sb_len);
 	tprintf("iovec_count=%d, ", sg_io->iovec_count);
 	tprintf("dxfer_len=%u, ", sg_io->dxfer_len);
 	tprintf("timeout=%u, ", sg_io->timeout);
@@ -74,28 +79,41 @@ print_sg_io_req(struct tcb *tcp, struct sg_io_hdr *sg_io)
 
 	if (sg_io->dxfer_direction == SG_DXFER_TO_DEV ||
 	    sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
-		tprintf(", data[%u]=[", sg_io->dxfer_len);
-		printstr(tcp, (unsigned long) sg_io->dxferp,
-			 sg_io->dxfer_len);
-		tprints("]");
+		tprintf(", data[%u]=", sg_io->dxfer_len);
+		if (sg_io->iovec_count)
+			tprint_iov_upto(tcp, sg_io->iovec_count,
+					(unsigned long)sg_io->dxferp, 1,
+					sg_io->dxfer_len);
+		else
+			print_sg_io_buffer(tcp, (unsigned long)sg_io->dxferp,
+					   sg_io->dxfer_len);
 	}
 }
 
 static void
 print_sg_io_res(struct tcb *tcp, struct sg_io_hdr *sg_io)
 {
+	uint32_t din_len;
+
 	if (sg_io->dxfer_direction == SG_DXFER_FROM_DEV ||
 	    sg_io->dxfer_direction == SG_DXFER_TO_FROM_DEV) {
-		tprintf(", data[%u]=[", sg_io->dxfer_len);
-		printstr(tcp, (unsigned long) sg_io->dxferp,
-			 sg_io->dxfer_len);
-		tprints("]");
+		din_len = sg_io->dxfer_len;
+		if (sg_io->resid > 0)
+			din_len -= sg_io->resid;
+		tprintf(", data[%u]=", din_len);
+		if (sg_io->iovec_count)
+			tprint_iov_upto(tcp, sg_io->iovec_count,
+					(unsigned long)sg_io->dxferp, 1,
+					din_len);
+		else
+			print_sg_io_buffer(tcp, (unsigned long)sg_io->dxferp,
+					   din_len);
 	}
 	tprintf(", status=%02x, ", sg_io->status);
 	tprintf("masked_status=%02x, ", sg_io->masked_status);
-	tprintf("sb[%u]=[", sg_io->sb_len_wr);
-	print_sg_io_buffer(tcp, sg_io->sbp, sg_io->sb_len_wr);
-	tprintf("], host_status=%#x, ", sg_io->host_status);
+	tprintf("sb[%u]=", sg_io->sb_len_wr);
+	print_sg_io_buffer(tcp, (unsigned long)sg_io->sbp, sg_io->sb_len_wr);
+	tprintf(", host_status=%#x, ", sg_io->host_status);
 	tprintf("driver_status=%#x, ", sg_io->driver_status);
 	tprintf("resid=%d, ", sg_io->resid);
 	tprintf("duration=%d, ", sg_io->duration);
-- 
2.1.4





More information about the Strace-devel mailing list