aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2007-05-08 05:15:48 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-08 12:55:19 -0400
commit801e0ced1891a2b8cad1a435c45234a719b3b6bf (patch)
tree9d7b203148f6040c855462d3eff20eae741de2b6
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>
-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,
4645 fsf_req->adapter = adapter; 4645 fsf_req->adapter = adapter;
4646 fsf_req->fsf_command = fsf_cmd; 4646 fsf_req->fsf_command = fsf_cmd;
4647 INIT_LIST_HEAD(&fsf_req->list); 4647 INIT_LIST_HEAD(&fsf_req->list);
4648
4649 /* this is serialized (we are holding req_queue-lock of adapter */
4650 if (adapter->req_no == 0)
4651 adapter->req_no++;
4652 fsf_req->req_id = adapter->req_no++;
4653
4654 init_timer(&fsf_req->timer); 4648 init_timer(&fsf_req->timer);
4655 zfcp_fsf_req_qtcb_init(fsf_req);
4656 4649
4657 /* initialize waitqueue which may be used to wait on 4650 /* initialize waitqueue which may be used to wait on
4658 this request completion */ 4651 this request completion */
4659 init_waitqueue_head(&fsf_req->completion_wq); 4652 init_waitqueue_head(&fsf_req->completion_wq);
4660 4653
4661 ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags); 4654 ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags);
4662 if(ret < 0) { 4655 if (ret < 0)
4663 goto failed_sbals; 4656 goto failed_sbals;
4664 } 4657
4658 /* this is serialized (we are holding req_queue-lock of adapter) */
4659 if (adapter->req_no == 0)
4660 adapter->req_no++;
4661 fsf_req->req_id = adapter->req_no++;
4662
4663 zfcp_fsf_req_qtcb_init(fsf_req);
4665 4664
4666 /* 4665 /*
4667 * We hold queue_lock here. Check if QDIOUP is set and let request fail 4666 * We hold queue_lock here. Check if QDIOUP is set and let request fail