aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
authorChristof Schmitt2007-05-08 11:15:48 +0200
committerJames Bottomley2007-05-08 11:55:19 -0500
commit801e0ced1891a2b8cad1a435c45234a719b3b6bf (patch)
tree9d7b203148f6040c855462d3eff20eae741de2b6 /drivers/s390
parent1d589edf9eeb60c9c8e62753d05cf4c8e094e5a7 (diff)
[SCSI] zfcp: Locking for req_no and req_seq_no
There is a possible race condition while generating the unique request ids and sequence numbers. Both might be read at the same time and have the same value. Fix this by serializing the access through the queue lock of the adapter: First call zfcp_fsf_req_sbal_get that acquires the lock, then read and increment the unique ids. Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index f120b16c77d5..07094c3dc341 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -4645,23 +4645,22 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
fsf_req->adapter = adapter;
fsf_req->fsf_command = fsf_cmd;
INIT_LIST_HEAD(&fsf_req->list);
-
- /* this is serialized (we are holding req_queue-lock of adapter */
- if (adapter->req_no == 0)
- adapter->req_no++;
- fsf_req->req_id = adapter->req_no++;
-
init_timer(&fsf_req->timer);
- zfcp_fsf_req_qtcb_init(fsf_req);
/* initialize waitqueue which may be used to wait on
this request completion */
init_waitqueue_head(&fsf_req->completion_wq);
ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags);
- if(ret < 0) {
+ if (ret < 0)
goto failed_sbals;
- }
+
+ /* this is serialized (we are holding req_queue-lock of adapter) */
+ if (adapter->req_no == 0)
+ adapter->req_no++;
+ fsf_req->req_id = adapter->req_no++;
+
+ zfcp_fsf_req_qtcb_init(fsf_req);
/*
* We hold queue_lock here. Check if QDIOUP is set and let request fail