Merged revisions 5984,5988-5989 via svnmerge from

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

........
  r5984 | vlnb | 2015-01-21 21:03:17 -0800 (Wed, 21 Jan 2015) | 9 lines
  
  [PATCH] scst_local: Fix bidirectional command support
  
  scsi_setup_cmnd() sets sc_data_direction to DMA_TO_DEVICE for bidirectional
  commands. Hence test SCpnt->request->next_rq instead of sc_data_direction
  to figure out whether or not a command is bidirectional.
  
  Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
........
  r5988 | vlnb | 2015-01-21 21:13:59 -0800 (Wed, 21 Jan 2015) | 27 lines
  
  scst_vdisk: Fix zero-copy read for tmpfs
  
  For some filesystems, e.g. tmpfs, address_space.readpage is NULL.
  Disable zero-copy reading for such filesystems. See also shmem_aops
  in mm/shmem.c. See also inode_init_always() and empty_aops in fs/inode.c.
  
  This patch avoids that the following call trace is triggered:
  
  BUG: unable to handle kernel NULL pointer dereference at (null)
  Call Trace:
   [<ffffffffa0547d66>] prepare_read+0x106/0x1d0 [scst_vdisk]
   [<ffffffffa0547f20>] fileio_alloc_data_buf+0xf0/0x330 [scst_vdisk]
   [<ffffffffa046fc9b>] scst_prepare_space+0x9b/0x6e0 [scst]
   [<ffffffffa047d4d5>] scst_process_active_cmd+0x545/0x840 [scst]
   [<ffffffffa047dad2>] scst_cmd_init_done+0x302/0x5d0 [scst]
   [<ffffffffa0563ab2>] scst_cmd_init_stage1_done.constprop.37+0x12/0x20 [iscsi_scst]
   [<ffffffffa056a9ea>] scsi_cmnd_start+0x25a/0x550 [iscsi_scst]
   [<ffffffffa056b4a8>] cmnd_rx_start+0x148/0x1a0 [iscsi_scst]
   [<ffffffffa056e4f8>] process_read_io+0x3b8/0x800 [iscsi_scst]
   [<ffffffffa056ea07>] scst_do_job_rd+0xc7/0x220 [iscsi_scst]
   [<ffffffffa056efed>] istrd+0x16d/0x2e0 [iscsi_scst]
   [<ffffffff81079efd>] kthread+0xed/0x110
   [<ffffffff817227fc>] ret_from_fork+0x7c/0xb0
  
  Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
........
  r5989 | vlnb | 2015-01-23 21:37:57 -0800 (Fri, 23 Jan 2015) | 5 lines
  
  scst_local: Rework data direction detection code
  
  Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
........


git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.0.x@6112 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2015-02-21 04:16:51 +00:00
parent 9da49a2f8f
commit 5c963d25e1
2 changed files with 15 additions and 21 deletions
+2 -1
View File
@@ -2686,7 +2686,8 @@ static int fileio_alloc_data_buf(struct scst_cmd *cmd)
* copy.
*/
if (cmd->tgt_i_data_buf_alloced ||
(cmd->data_direction & SCST_DATA_READ) == 0) {
(cmd->data_direction & SCST_DATA_READ) == 0 ||
(virt_dev->fd && !virt_dev->fd->f_mapping->a_ops->readpage)) {
p->use_zero_copy = false;
}
if (!p->use_zero_copy)
+13 -20
View File
@@ -1068,22 +1068,8 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
sgl_count = scsi_sg_count(SCpnt);
#endif
dir = SCST_DATA_NONE;
switch (SCpnt->sc_data_direction) {
case DMA_TO_DEVICE:
dir = SCST_DATA_WRITE;
scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt));
scst_cmd_set_noio_mem_alloc(scst_cmd);
scst_cmd_set_tgt_sg(scst_cmd, sgl, sgl_count);
break;
case DMA_FROM_DEVICE:
dir = SCST_DATA_READ;
scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt));
scst_cmd_set_noio_mem_alloc(scst_cmd);
scst_cmd_set_tgt_sg(scst_cmd, sgl, sgl_count);
break;
case DMA_BIDIRECTIONAL:
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24))
if (scsi_bidi_cmnd(SCpnt)) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24)
/* Some of these symbols are only defined after 2.6.24 */
dir = SCST_DATA_BIDI;
scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt));
@@ -1093,13 +1079,20 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
scst_cmd_set_tgt_sg(scst_cmd, scsi_in(SCpnt)->table.sgl,
scsi_in(SCpnt)->table.nents);
scst_cmd_set_tgt_out_sg(scst_cmd, sgl, sgl_count);
break;
#endif
case DMA_NONE:
default:
} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
dir = SCST_DATA_WRITE;
scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt));
scst_cmd_set_noio_mem_alloc(scst_cmd);
scst_cmd_set_tgt_sg(scst_cmd, sgl, sgl_count);
} else if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
dir = SCST_DATA_READ;
scst_cmd_set_expected(scst_cmd, dir, scsi_bufflen(SCpnt));
scst_cmd_set_noio_mem_alloc(scst_cmd);
scst_cmd_set_tgt_sg(scst_cmd, sgl, sgl_count);
} else {
dir = SCST_DATA_NONE;
scst_cmd_set_expected(scst_cmd, dir, 0);
break;
}
/* Save the correct thing below depending on version */