From 5c4bd85b80825a6706a90e5c3792b8bccb4cc257 Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Fri, 27 Mar 2015 09:53:23 +0100 Subject: [PATCH] nop: clear immediate flag in iscsi_nop_out_async originally NOPs where used to detect failures in the transport layer. This is e.g. implemented in qemu since a few years now. Recently I found a few vServers with hanging I/O where the NOP mechanism could not detect the error. The reason is most likely due to a bug in the target, however if NOPs increase the CmdSN this could help to detect such failures. If there are requests hanging and the OS stops I/O before CmdSN > MaxCmdSN we can currently send NOPs forever and they might still be answered. If a NOP increases the CmdSN we will enter a point where CmdSN is greater than MaxCmdSN. This is, of course, not the ideal check, but it might detect some types of errors. Ideally we would send out a Test-Unit-Ready command with attr=ordered, but that requires a new API and/or modification of the tool that uses libiscsi. This here comes with no modification for the userspace. Signed-off-by: Peter Lieven --- lib/nop.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/nop.c b/lib/nop.c index 2a8c0dc..f6ba56f 100644 --- a/lib/nop.c +++ b/lib/nop.c @@ -46,9 +46,6 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, return -1; } - /* immediate flag */ - iscsi_pdu_set_immediate(pdu); - /* flags */ iscsi_pdu_set_pduflags(pdu, 0x80); @@ -58,12 +55,11 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, /* lun */ iscsi_pdu_set_lun(pdu, 0); - /* cmdsn is not increased if Immediate delivery*/ iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn); - pdu->cmdsn = iscsi->cmdsn; + pdu->cmdsn = iscsi->cmdsn++; /* exp statsn */ - iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1); + iscsi_pdu_set_expstatsn(pdu, iscsi->statsn + 1); pdu->callback = cb; pdu->private_data = private_data; @@ -141,6 +137,7 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6, "NOP Out Reply received"); + iscsi_adjust_maxexpcmdsn(iscsi, in); iscsi->nops_in_flight = 0; if (pdu->callback == NULL) {