aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2014-08-02 19:51:10 +0000
committerAlexander Motin <mav@FreeBSD.org>2014-08-02 19:51:10 +0000
commit43d2d7195362e00e6eb7e0b7d715ce483daa574e (patch)
tree6dce5604a761a9f6e4e5b12547a1d1b6f452d0a7 /sys/cam/ctl
parentb2c5bf0de2c04d948dab36a9b4d86d38352e9e8e (diff)
downloadsrc-43d2d7195362e00e6eb7e0b7d715ce483daa574e.tar.gz
src-43d2d7195362e00e6eb7e0b7d715ce483daa574e.zip
Add missing comparisons to make list IDs in EXTENDED COPY per-initiator,
as they should be. Wrap it into a function to not duplicate the code. MFC after: 3 days
Notes
Notes: svn path=/head/; revision=269441
Diffstat (limited to 'sys/cam/ctl')
-rw-r--r--sys/cam/ctl/ctl_tpc.c59
1 files changed, 26 insertions, 33 deletions
diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c
index ad66ca9961bd..01804757dcf9 100644
--- a/sys/cam/ctl/ctl_tpc.c
+++ b/sys/cam/ctl/ctl_tpc.c
@@ -327,6 +327,21 @@ ctl_receive_copy_operating_parameters(struct ctl_scsiio *ctsio)
return (retval);
}
+static struct tpc_list *
+tpc_find_list(struct ctl_lun *lun, uint32_t list_id, uint32_t init_idx)
+{
+ struct tpc_list *list;
+
+ mtx_assert(&lun->lun_lock, MA_OWNED);
+ TAILQ_FOREACH(list, &lun->tpc_lists, links) {
+ if ((list->flags & EC_LIST_ID_USAGE_MASK) !=
+ EC_LIST_ID_USAGE_NONE && list->list_id == list_id &&
+ list->init_idx == init_idx)
+ break;
+ }
+ return (list);
+}
+
int
ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio)
{
@@ -348,11 +363,8 @@ ctl_receive_copy_status_lid1(struct ctl_scsiio *ctsio)
list_id = cdb->list_identifier;
mtx_lock(&lun->lun_lock);
- TAILQ_FOREACH(list, &lun->tpc_lists, links) {
- if ((list->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE && list->list_id == list_id)
- break;
- }
+ list = tpc_find_list(lun, list_id,
+ ctl_get_resindex(&ctsio->io_hdr.nexus));
if (list == NULL) {
mtx_unlock(&lun->lun_lock);
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1,
@@ -433,12 +445,9 @@ ctl_receive_copy_failure_details(struct ctl_scsiio *ctsio)
list_id = cdb->list_identifier;
mtx_lock(&lun->lun_lock);
- TAILQ_FOREACH(list, &lun->tpc_lists, links) {
- if (list->completed && (list->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE && list->list_id == list_id)
- break;
- }
- if (list == NULL) {
+ list = tpc_find_list(lun, list_id,
+ ctl_get_resindex(&ctsio->io_hdr.nexus));
+ if (list == NULL || !list->completed) {
mtx_unlock(&lun->lun_lock);
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1,
/*command*/ 1, /*field*/ 2, /*bit_valid*/ 0,
@@ -507,11 +516,8 @@ ctl_receive_copy_status_lid4(struct ctl_scsiio *ctsio)
list_id = scsi_4btoul(cdb->list_identifier);
mtx_lock(&lun->lun_lock);
- TAILQ_FOREACH(list, &lun->tpc_lists, links) {
- if ((list->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE && list->list_id == list_id)
- break;
- }
+ list = tpc_find_list(lun, list_id,
+ ctl_get_resindex(&ctsio->io_hdr.nexus));
if (list == NULL) {
mtx_unlock(&lun->lun_lock);
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1,
@@ -596,11 +602,8 @@ ctl_copy_operation_abort(struct ctl_scsiio *ctsio)
list_id = scsi_4btoul(cdb->list_identifier);
mtx_lock(&lun->lun_lock);
- TAILQ_FOREACH(list, &lun->tpc_lists, links) {
- if ((list->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE && list->list_id == list_id)
- break;
- }
+ list = tpc_find_list(lun, list_id,
+ ctl_get_resindex(&ctsio->io_hdr.nexus));
if (list == NULL) {
mtx_unlock(&lun->lun_lock);
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1,
@@ -1210,12 +1213,7 @@ ctl_extended_copy_lid1(struct ctl_scsiio *ctsio)
list->lun = lun;
mtx_lock(&lun->lun_lock);
if ((list->flags & EC_LIST_ID_USAGE_MASK) != EC_LIST_ID_USAGE_NONE) {
- TAILQ_FOREACH(tlist, &lun->tpc_lists, links) {
- if ((tlist->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE &&
- tlist->list_id == list->list_id)
- break;
- }
+ tlist = tpc_find_list(lun, list->list_id, list->init_idx);
if (tlist != NULL && !tlist->completed) {
mtx_unlock(&lun->lun_lock);
free(list, M_CTL);
@@ -1338,12 +1336,7 @@ ctl_extended_copy_lid4(struct ctl_scsiio *ctsio)
list->lun = lun;
mtx_lock(&lun->lun_lock);
if ((list->flags & EC_LIST_ID_USAGE_MASK) != EC_LIST_ID_USAGE_NONE) {
- TAILQ_FOREACH(tlist, &lun->tpc_lists, links) {
- if ((tlist->flags & EC_LIST_ID_USAGE_MASK) !=
- EC_LIST_ID_USAGE_NONE &&
- tlist->list_id == list->list_id)
- break;
- }
+ tlist = tpc_find_list(lun, list->list_id, list->init_idx);
if (tlist != NULL && !tlist->completed) {
mtx_unlock(&lun->lun_lock);
free(list, M_CTL);