Merged revisions 5933,5940 via svnmerge from

svn+ssh://vlnb@svn.code.sf.net/p/scst/svn/trunk

........
  r5933 | vlnb | 2014-12-10 20:38:04 -0800 (Wed, 10 Dec 2014) | 11 lines
  
  vdisk_blockio: Report invalid scatterlists
  
  It is possible for a target driver to pass a scatterlist via
  scst_cmd_set_tgt_sg() that is valid for the vdisk_fileio handler
  but not for the vdisk_blockio handler. Complain loudly if an invalid
  scatterlist is passed to vdisk_blockio because such scatterlists
  cause silent data corruption with most Linux block drivers.
  
  Signed-off-by: Bart Van Assche <bvanassche@acm.org>
........
  r5940 | vlnb | 2014-12-18 19:55:14 -0800 (Thu, 18 Dec 2014) | 7 lines
  
  Replace in cases, where sporadic failures are possible, HARDWARE ERROR
  by INTERNAL TARGET FAILURE, which is retriable (some OS'es don't retry
  HARDWARE ERROR)
  
  Reported and suggested by Shahar Salzman <shahar.salzman@kaminario.com>
........


git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.0.x@6109 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2015-02-21 04:07:53 +00:00
parent b627ccf92f
commit b1c8432588
10 changed files with 55 additions and 38 deletions
+4 -2
View File
@@ -5823,8 +5823,10 @@ static void q2t_on_hw_pending_cmd_timeout(struct scst_cmd *scst_cmd)
q2t_cleanup_hw_pending_cmd(ha, cmd);
scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_FATAL,
SCST_CONTEXT_THREAD);
/* It might be sporadic, hence retriable */
scst_set_cmd_error(scst_cmd,
SCST_LOAD_SENSE(scst_sense_internal_failure));
scst_rx_data(scst_cmd, SCST_RX_STATUS_ERROR_SENSE_SET, SCST_CONTEXT_THREAD);
goto out_unlock;
} else if (cmd->state == Q2T_STATE_ABORTED) {
TRACE_MGMT_DBG("Force finishing aborted cmd %p (tag %d)",
+2 -1
View File
@@ -298,7 +298,7 @@ static inline int scst_sense_response_code(const uint8_t *sense)
#define scst_sense_read_error MEDIUM_ERROR, 0x11, 0
/* HARDWARE_ERROR is 4 */
#define scst_sense_hardw_error HARDWARE_ERROR, 0x44, 0
#define scst_sense_hardw_error HARDWARE_ERROR, 0x44, 0 /* non-retriable */
/* ILLEGAL_REQUEST is 5 */
#define scst_sense_invalid_opcode ILLEGAL_REQUEST, 0x20, 0
@@ -333,6 +333,7 @@ static inline int scst_sense_response_code(const uint8_t *sense)
/* ABORTED_COMMAND is 0xb */
#define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0
#define scst_sense_internal_failure ABORTED_COMMAND, 0x44, 0 /* retriable */
/* MISCOMPARE is 0xe */
#define scst_sense_miscompare_error MISCOMPARE, 0x1D, 0
+1 -1
View File
@@ -536,7 +536,7 @@ out:
return res;
out_err_restore:
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out_restore;
out_error:
+1 -1
View File
@@ -291,7 +291,7 @@ static int tape_done(struct scst_cmd *cmd)
PRINT_ERROR("Sense format 0x%x is not supported",
scst_sense_response_code(cmd->sense));
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
+12 -12
View File
@@ -1260,7 +1260,7 @@ out_unmap:
ucmd->data_pages = NULL;
res = -EFAULT;
if (ucmd->cmd != NULL)
scst_set_cmd_error(ucmd->cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
scst_set_cmd_error(ucmd->cmd, SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out_err;
}
@@ -1377,8 +1377,8 @@ out_inval:
res = -EINVAL;
goto out_abnormal;
out_hwerr_res_set:
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
out_intern_fail_res_set:
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_internal_failure));
out_abnormal:
scst_set_cmd_abnormal_done_state(cmd);
@@ -1393,7 +1393,7 @@ out_status:
res = scst_alloc_sense(cmd, 0);
if (res != 0)
goto out_hwerr_res_set;
goto out_intern_fail_res_set;
sense_len = min_t(int, cmd->sense_buflen, preply->sense_len);
@@ -1403,7 +1403,7 @@ out_status:
if (rc != 0) {
PRINT_ERROR("Failed to copy %d sense's bytes", rc);
res = -EFAULT;
goto out_hwerr_res_set;
goto out_intern_fail_res_set;
}
cmd->sense_valid_len = sense_len;
}
@@ -1495,7 +1495,7 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd,
if (unlikely((ereply->pbuf & ~PAGE_MASK) != 0)) {
PRINT_ERROR("Supplied pbuf %llx isn't "
"page aligned", ereply->pbuf);
goto out_hwerr;
goto out_intern_fail;
}
pages = cmd->sg_cnt;
} else
@@ -1540,7 +1540,7 @@ static int dev_user_process_reply_exec(struct scst_user_cmd *ucmd,
if (rc != 0) {
PRINT_ERROR("Failed to copy %d sense's bytes", rc);
res = -EFAULT;
goto out_hwerr_res_set;
goto out_intern_fail_res_set;
}
cmd->sense_valid_len = sense_len;
}
@@ -1560,16 +1560,16 @@ out_inval:
(long long unsigned int)cmd->lun, scst_get_opcode_name(cmd), cmd);
PRINT_BUFFER("Invalid exec_reply", reply, sizeof(*reply));
out_hwerr:
out_intern_fail:
res = -EINVAL;
out_hwerr_res_set:
out_intern_fail_res_set:
if (ucmd->background_exec) {
ucmd_put(ucmd);
goto out;
} else {
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out_compl;
}
@@ -2261,7 +2261,7 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy,
scst_set_busy(ucmd->cmd);
else
scst_set_cmd_error(ucmd->cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
scst_set_cmd_abnormal_done_state(ucmd->cmd);
@@ -2292,7 +2292,7 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy,
scst_set_busy(ucmd->cmd);
else
scst_set_cmd_error(ucmd->cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
ucmd->cmd->scst_cmd_done(ucmd->cmd, SCST_CMD_STATE_DEFAULT,
+26 -12
View File
@@ -4787,7 +4787,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p)
if (unlikely(length < 0)) {
PRINT_ERROR("scst_get_buf_first() failed: %zd", length);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
@@ -4816,7 +4816,7 @@ static enum compl_status_e fileio_exec_read(struct vdisk_cmd_params *p)
} else if (unlikely(length < 0)) {
PRINT_ERROR("scst_get_buf_next() failed: %zd", length);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out_set_fs;
}
@@ -4910,7 +4910,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p)
if (unlikely(length < 0)) {
PRINT_ERROR("scst_get_buf_first() failed: %zd", length);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
@@ -4939,7 +4939,7 @@ static enum compl_status_e fileio_exec_write(struct vdisk_cmd_params *p)
} else if (unlikely(length < 0)) {
PRINT_ERROR("scst_get_buf_next() failed: %zd", length);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out_set_fs;
}
@@ -5176,8 +5176,10 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
/* Allocate and initialize blockio_work struct */
blockio_work = kmem_cache_alloc(blockio_work_cachep, gfp_mask);
if (blockio_work == NULL)
goto out_no_mem;
if (blockio_work == NULL) {
scst_set_busy(cmd);
goto finish_cmd;
}
#if 0
{
@@ -5199,6 +5201,18 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
need_new_bio = 1;
length = scst_get_sg_page_first(cmd, &page, &offset);
/*
* bv_len and bv_offset must be a multiple of 512 (SECTOR_SIZE), so
* check this here.
*/
if (WARN_ONCE((length & 511) != 0 || (offset & 511) != 0,
"Refused bio with invalid length %d and/or offset %d.\n",
length, offset)) {
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
goto free_bio;
}
while (length > 0) {
int len, bytes, off, thislen;
struct page *pg;
@@ -5219,7 +5233,8 @@ static void blockio_exec_rw(struct vdisk_cmd_params *p, bool write, bool fua)
PRINT_ERROR("Failed to create bio "
"for data segment %d (cmd %p)",
cmd->get_sg_buf_entry_num, cmd);
goto out_no_bio;
scst_set_busy(cmd);
goto free_bio;
}
bios++;
@@ -5303,7 +5318,7 @@ out:
TRACE_EXIT();
return;
out_no_bio:
free_bio:
while (hbio) {
bio = hbio;
hbio = hbio->bi_next;
@@ -5311,8 +5326,7 @@ out_no_bio:
}
kmem_cache_free(blockio_work_cachep, blockio_work);
out_no_mem:
scst_set_busy(cmd);
finish_cmd:
cmd->completed = 1;
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
goto out;
@@ -5677,7 +5691,7 @@ static enum compl_status_e vdev_exec_verify(struct vdisk_cmd_params *p)
if (length < 0) {
PRINT_ERROR("scst_get_buf_() failed: %zd", length);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
out_free:
@@ -5735,7 +5749,7 @@ static enum compl_status_e vdisk_exec_caw(struct vdisk_cmd_params *p)
scst_set_busy(cmd);
else
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
+3 -3
View File
@@ -4959,7 +4959,7 @@ static void scst_complete_request_sense(struct scst_cmd *req_cmd)
PRINT_ERROR("%s", "Unable to get the sense via "
"REQUEST SENSE, returning HARDWARE ERROR");
scst_set_cmd_error(orig_cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
}
@@ -6483,7 +6483,7 @@ int scst_get_buf_full_sense(struct scst_cmd *cmd, uint8_t **buf)
scst_set_busy(cmd);
else
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
@@ -10505,7 +10505,7 @@ void tm_dbg_release_cmd(struct scst_cmd *cmd)
if (((scst_random() % 10) == 5)) {
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(
scst_sense_hardw_error));
scst_sense_internal_failure));
/* It's completed now */
}
}
+1 -1
View File
@@ -1032,7 +1032,7 @@ out:
* the affected initiator.
*/
if (cmd != NULL)
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_internal_failure));
#endif
}
+4 -4
View File
@@ -3516,7 +3516,7 @@ static bool scst_check_auto_sense(struct scst_cmd *cmd)
"%s)", cmd->host_status, cmd, scst_get_opcode_name(cmd),
cmd->tgt->tgt_name, cmd->dev->virt_name);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
}
@@ -3544,7 +3544,7 @@ static int scst_pre_dev_done(struct scst_cmd *cmd)
PRINT_ERROR("%s", "Unable to issue REQUEST SENSE, "
"returning HARDWARE ERROR");
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
}
goto out;
}
@@ -3580,7 +3580,7 @@ next:
"MODE_SENSE buffer");
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(
scst_sense_hardw_error));
scst_sense_internal_failure));
err = true;
} else if (length > 2 && cmd->cdb[0] == MODE_SENSE)
address[2] |= 0x80; /* Write Protect*/
@@ -3621,7 +3621,7 @@ next:
PRINT_ERROR("%s", "Unable to get INQUIRY "
"buffer");
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_hardw_error));
SCST_LOAD_SENSE(scst_sense_internal_failure));
err = true;
}
if (buflen > 0)
+1 -1
View File
@@ -209,7 +209,7 @@ static int do_exec(struct vdisk_cmd *vcmd)
#ifdef DEBUG_SENSE
if ((random() % 100000) == 75) {
set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_internal_failure));
goto out;
}
#endif