diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 11a077f25..54aefe7c1 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -303,6 +303,7 @@ static inline int scst_sense_response_code(const uint8_t *sense) #define scst_sense_saving_params_unsup ILLEGAL_REQUEST, 0x39, 0 #define scst_sense_invalid_message ILLEGAL_REQUEST, 0x49, 0 #define scst_sense_parameter_list_length_invalid ILLEGAL_REQUEST, 0x1A, 0 +#define scst_sense_invalid_field_in_command_information_unit ILLEGAL_REQUEST, 0xE, 0x3 /* UNIT_ATTENTION is 6 */ #define scst_sense_medium_changed_UA UNIT_ATTENTION, 0x28, 0 diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index adb3764fb..af1940804 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -1545,8 +1545,22 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd) do_zero = true; } if (do_zero) { - scst_check_restore_sg_buff(cmd); - scst_zero_write_rest(cmd); + if ((cmd->write_len & ((1 << cmd->dev->block_shift) - 1)) == 0) { + scst_check_restore_sg_buff(cmd); + scst_zero_write_rest(cmd); + } else { + /* + * Looks like it's safer in this case to + * return error instead of zeroing + * the rest to prevent initiators lost + * in 4K and 512 bytes blocks, i.e. + * sending commands on 4K blocks devices + * thinking that they have 512 bytes + * blocks, from corrupting data. + */ + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_field_in_command_information_unit)); + } } } }