mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 05:01:27 +00:00
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> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5933 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -5319,8 +5319,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
|
||||
{
|
||||
@@ -5345,6 +5347,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;
|
||||
@@ -5370,7 +5384,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++;
|
||||
@@ -5457,7 +5472,7 @@ out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
|
||||
out_no_bio:
|
||||
free_bio:
|
||||
while (hbio) {
|
||||
bio = hbio;
|
||||
hbio = hbio->bi_next;
|
||||
@@ -5465,8 +5480,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;
|
||||
|
||||
Reference in New Issue
Block a user