diff --git a/scst/include/scst.h b/scst/include/scst.h index c96079004..bdc18d9bf 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -5124,7 +5124,7 @@ static inline int scst_get_out_buf_count(struct scst_cmd *cmd) return (cmd->out_sg_cnt == 0) ? 1 : cmd->out_sg_cnt; } -int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf); +int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf, bool always_copy); int scst_get_buf_full_sense(struct scst_cmd *cmd, uint8_t **buf); void scst_put_buf_full(struct scst_cmd *cmd, uint8_t *buf); diff --git a/scst/src/scst_copy_mgr.c b/scst/src/scst_copy_mgr.c index 344b69e37..e8808a465 100644 --- a/scst/src/scst_copy_mgr.c +++ b/scst/src/scst_copy_mgr.c @@ -2352,7 +2352,7 @@ static void scst_cm_init_inq_finish(struct scst_cmd *cmd) goto out; } - length = scst_get_buf_full(cmd, &buf); + length = scst_get_buf_full(cmd, &buf, false); TRACE_DBG("length %d", length); if (unlikely(length <= 0)) { if (length < 0) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index fca89fd62..9b8a1c831 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5918,7 +5918,7 @@ static void scst_complete_request_sense(struct scst_cmd *req_cmd) sBUG_ON(orig_cmd == NULL); - len = scst_get_buf_full(req_cmd, &buf); + len = scst_get_buf_full(req_cmd, &buf, false); if (scsi_status_is_good(req_cmd->status) && (len > 0) && scst_sense_valid(buf)) { @@ -9071,12 +9071,13 @@ EXPORT_SYMBOL_GPL(scst_copy_sg); * scst_get_buf_full - return linear buffer for command * @cmd: scst command * @buf: pointer on the resulting pointer + * @always_copy: copy the data buffer even for commands that read data * * If the command's buffer >single page, it vmalloc() the needed area * and copies the buffer there. Returns length of the buffer or negative * error code otherwise. */ -int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf) +int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf, bool always_copy) { int res = 0; @@ -9111,7 +9112,8 @@ int scst_get_buf_full(struct scst_cmd *cmd, uint8_t **buf) } cmd->sg_buff_vmallocated = 1; - if (scst_cmd_get_data_direction(cmd) == SCST_DATA_WRITE) { + if (scst_cmd_get_data_direction(cmd) == SCST_DATA_WRITE || + always_copy) { uint8_t *buf_ptr; buf_ptr = *buf; @@ -9149,7 +9151,7 @@ int scst_get_buf_full_sense(struct scst_cmd *cmd, uint8_t **buf) TRACE_ENTRY(); - res = scst_get_buf_full(cmd, buf); + res = scst_get_buf_full(cmd, buf, false); if (unlikely(res < 0)) { PRINT_ERROR("scst_get_buf_full() failed: %d", res); if (res == -ENOMEM) @@ -12531,7 +12533,7 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd, int buffer_size, sector_size, sh; uint8_t *buffer; - buffer_size = scst_get_buf_full(cmd, &buffer); + buffer_size = scst_get_buf_full(cmd, &buffer, false); sect_sz_off = opcode == READ_CAPACITY ? 4 : 8; if (buffer_size < sect_sz_off + 4) { scst_put_buf_full(cmd, buffer); @@ -12577,7 +12579,7 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd, switch (opcode) { case MODE_SENSE: case MODE_SELECT: - buffer_size = scst_get_buf_full(cmd, &buffer); + buffer_size = scst_get_buf_full(cmd, &buffer, false); if (unlikely(buffer_size <= 0)) { if (buffer_size < 0) { PRINT_ERROR("%s: Unable to get the buffer (%d)", diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 82b9bfc1a..d12984996 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -4150,7 +4150,7 @@ next: uint8_t *address; bool err = false; - length = scst_get_buf_full(cmd, &address); + length = scst_get_buf_full(cmd, &address, true); if (length < 0) { PRINT_ERROR("%s", "Unable to get " "MODE_SENSE buffer"); diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 0f0fb9fcf..1b60c4d0c 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -1695,7 +1695,7 @@ int scst_tg_set_group_info(struct scst_cmd *cmd) TRACE_ENTRY(); - len = scst_get_buf_full(cmd, &buf); + len = scst_get_buf_full(cmd, &buf, false); if (len < 0) { PRINT_ERROR("scst_get_buf_full() failed: %d", len); res = len;