| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Generic SCSI-3 ALUA SCSI Device Handler |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007-2010 Hannes Reinecke, SUSE Linux Products GmbH. |
|---|
| 5 | 6 | * All rights reserved. |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU General Public License for more details. |
|---|
| 16 | | - * |
|---|
| 17 | | - * You should have received a copy of the GNU General Public License |
|---|
| 18 | | - * along with this program; if not, write to the Free Software |
|---|
| 19 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|---|
| 20 | | - * |
|---|
| 21 | 7 | */ |
|---|
| 22 | 8 | #include <linux/slab.h> |
|---|
| 23 | 9 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 1050 | 1036 | rcu_read_unlock(); |
|---|
| 1051 | 1037 | mutex_unlock(&h->init_mutex); |
|---|
| 1052 | 1038 | |
|---|
| 1053 | | - if (alua_rtpg_queue(pg, sdev, qdata, true)) |
|---|
| 1039 | + if (alua_rtpg_queue(pg, sdev, qdata, true)) { |
|---|
| 1054 | 1040 | fn = NULL; |
|---|
| 1055 | | - else |
|---|
| 1041 | + } else { |
|---|
| 1042 | + kfree(qdata); |
|---|
| 1056 | 1043 | err = SCSI_DH_DEV_OFFLINED; |
|---|
| 1044 | + } |
|---|
| 1057 | 1045 | kref_put(&pg->kref, release_port_group); |
|---|
| 1058 | 1046 | out: |
|---|
| 1059 | 1047 | if (fn) |
|---|
| .. | .. |
|---|
| 1090 | 1078 | * Fail I/O to all paths not in state |
|---|
| 1091 | 1079 | * active/optimized or active/non-optimized. |
|---|
| 1092 | 1080 | */ |
|---|
| 1093 | | -static int alua_prep_fn(struct scsi_device *sdev, struct request *req) |
|---|
| 1081 | +static blk_status_t alua_prep_fn(struct scsi_device *sdev, struct request *req) |
|---|
| 1094 | 1082 | { |
|---|
| 1095 | 1083 | struct alua_dh_data *h = sdev->handler_data; |
|---|
| 1096 | 1084 | struct alua_port_group *pg; |
|---|
| 1097 | 1085 | unsigned char state = SCSI_ACCESS_STATE_OPTIMAL; |
|---|
| 1098 | | - int ret = BLKPREP_OK; |
|---|
| 1099 | 1086 | |
|---|
| 1100 | 1087 | rcu_read_lock(); |
|---|
| 1101 | 1088 | pg = rcu_dereference(h->pg); |
|---|
| 1102 | 1089 | if (pg) |
|---|
| 1103 | 1090 | state = pg->state; |
|---|
| 1104 | 1091 | rcu_read_unlock(); |
|---|
| 1105 | | - if (state == SCSI_ACCESS_STATE_TRANSITIONING) |
|---|
| 1106 | | - ret = BLKPREP_DEFER; |
|---|
| 1107 | | - else if (state != SCSI_ACCESS_STATE_OPTIMAL && |
|---|
| 1108 | | - state != SCSI_ACCESS_STATE_ACTIVE && |
|---|
| 1109 | | - state != SCSI_ACCESS_STATE_LBA) { |
|---|
| 1110 | | - ret = BLKPREP_KILL; |
|---|
| 1111 | | - req->rq_flags |= RQF_QUIET; |
|---|
| 1112 | | - } |
|---|
| 1113 | | - return ret; |
|---|
| 1114 | 1092 | |
|---|
| 1093 | + switch (state) { |
|---|
| 1094 | + case SCSI_ACCESS_STATE_OPTIMAL: |
|---|
| 1095 | + case SCSI_ACCESS_STATE_ACTIVE: |
|---|
| 1096 | + case SCSI_ACCESS_STATE_LBA: |
|---|
| 1097 | + return BLK_STS_OK; |
|---|
| 1098 | + case SCSI_ACCESS_STATE_TRANSITIONING: |
|---|
| 1099 | + return BLK_STS_RESOURCE; |
|---|
| 1100 | + default: |
|---|
| 1101 | + req->rq_flags |= RQF_QUIET; |
|---|
| 1102 | + return BLK_STS_IOERR; |
|---|
| 1103 | + } |
|---|
| 1115 | 1104 | } |
|---|
| 1116 | 1105 | |
|---|
| 1117 | 1106 | static void alua_rescan(struct scsi_device *sdev) |
|---|