diff options
author | Lee Duncan <lduncan@suse.com> | 2020-11-06 11:33:17 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-12-02 08:29:28 +0100 |
commit | dd069602398522a76a339296bec086a72ef594d1 (patch) | |
tree | f18fc97917caa926cc19c7e7066ea996ac31c7e7 /include/scsi | |
parent | 94920347ede62cb31a35a7e789fd612cc682e8b0 (diff) | |
download | linux-stable-dd069602398522a76a339296bec086a72ef594d1.tar.gz linux-stable-dd069602398522a76a339296bec086a72ef594d1.tar.bz2 linux-stable-dd069602398522a76a339296bec086a72ef594d1.zip |
scsi: libiscsi: Fix NOP race condition
[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]
iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:
iscsid: Got nop in, but kernel supports nop handling.
This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.
To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").
Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.duncan@gmail.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include/scsi')
-rw-r--r-- | include/scsi/libiscsi.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index c7b1dc713cdd..9c7f4aad6db6 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -144,6 +144,9 @@ struct iscsi_task { void *dd_data; /* driver/transport data */ }; +/* invalid scsi_task pointer */ +#define INVALID_SCSI_TASK (struct iscsi_task *)-1l + static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) { return task->unsol_r2t.data_length > task->unsol_r2t.sent; |