From patchwork Thu Nov 19 12:25:03 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 61283 Received: from hormel.redhat.com (hormel1.redhat.com [209.132.177.33]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nAJCPMfS016660 for ; Thu, 19 Nov 2009 12:25:22 GMT Received: from listman.util.phx.redhat.com (listman.util.phx.redhat.com [10.8.4.110]) by hormel.redhat.com (Postfix) with ESMTP id 11DB861BD97; Thu, 19 Nov 2009 07:25:22 -0500 (EST) Received: from int-mx03.intmail.prod.int.phx2.redhat.com (nat-pool.util.phx.redhat.com [10.8.5.200]) by listman.util.phx.redhat.com (8.13.1/8.13.1) with ESMTP id nAJCPJpM024746 for ; Thu, 19 Nov 2009 07:25:19 -0500 Received: from mx1.redhat.com (ext-mx01.extmail.prod.ext.phx2.redhat.com [10.5.110.5]) by int-mx03.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nAJCPJQl001269 for ; Thu, 19 Nov 2009 07:25:19 -0500 Received: from mx1.suse.de (cantor.suse.de [195.135.220.2]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nAJCP3QJ010118 for ; Thu, 19 Nov 2009 07:25:04 -0500 Received: from relay1.suse.de (mail2.suse.de [195.135.221.8]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 69D43945D6; Thu, 19 Nov 2009 13:25:03 +0100 (CET) Date: Thu, 19 Nov 2009 13:25:03 +0100 To: James Bottomley User-Agent: Heirloom mailx 12.2 01/07/07 MIME-Version: 1.0 Message-Id: <20091119122503.413AD3A174@ochil.suse.de> From: hare@suse.de (Hannes Reinecke) X-RedHat-Spam-Score: -5.941 (AWL,RCVD_IN_DNSWL_HI) X-Scanned-By: MIMEDefang 2.67 on 10.5.11.16 X-Scanned-By: MIMEDefang 2.67 on 10.5.110.5 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, linux-scsi@vger.kernel.org Subject: [dm-devel] [PATCH] multipath: Evaluate request result and sense code X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.5 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index dce971d..460e11f 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #define DM_MSG_PREFIX "multipath" @@ -101,6 +102,7 @@ struct multipath { struct dm_mpath_io { struct pgpath *pgpath; size_t nr_bytes; + char sense[SCSI_SENSE_BUFFERSIZE]; }; typedef int (*action_fn) (struct pgpath *pgpath); @@ -913,6 +915,9 @@ static int multipath_map(struct dm_target *ti, struct request *clone, map_context->ptr = mpio; clone->cmd_flags |= REQ_FAILFAST_TRANSPORT; + /* Always attach a sense buffer */ + if (!clone->sense) + clone->sense = mpio->sense; r = map_io(m, clone, mpio, 0); if (r < 0 || r == DM_MAPIO_REQUEUE) mempool_free(mpio, m->mpio_pool); @@ -1192,6 +1197,42 @@ static void activate_path(struct work_struct *work) } /* + * Evaluate scsi return code + */ +static int eval_scsi_error(int result, char *sense, int sense_len) +{ + struct scsi_sense_hdr sshdr; + int r = DM_ENDIO_REQUEUE; + + if (host_byte(result) != DID_OK) + return r; + + if (msg_byte(result) != COMMAND_COMPLETE) + return r; + + if (status_byte(result) == RESERVATION_CONFLICT) + /* Do not retry here, possible data corruption */ + return -EIO; + + if (status_byte(result) == CHECK_CONDITION && + !scsi_normalize_sense(sense, sense_len, &sshdr)) { + + switch (sshdr.sense_key) { + case MEDIUM_ERROR: + case DATA_PROTECT: + case BLANK_CHECK: + case COPY_ABORTED: + case VOLUME_OVERFLOW: + case MISCOMPARE: + r = -EIO; + break; + } + } + + return r; +} + +/* * end_io handling */ static int do_end_io(struct multipath *m, struct request *clone, @@ -1217,6 +1258,10 @@ static int do_end_io(struct multipath *m, struct request *clone, if (error == -EOPNOTSUPP) return error; + r = eval_scsi_error(clone->errors, clone->sense, clone->sense_len); + if (r != DM_ENDIO_REQUEUE) + return r; + if (mpio->pgpath) fail_path(mpio->pgpath); @@ -1243,6 +1288,10 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone, if (ps->type->end_io) ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); } + if (clone->sense == mpio->sense) { + clone->sense = NULL; + clone->sense_len = 0; + } mempool_free(mpio, m->mpio_pool); return r;