mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 10:41:26 +00:00
Modified patch from Bart Van Assche <bvanassche@acm.org>:
The range unmapped by the scst_vdisk handler when processing an UNMAP command is not correct. The patch below fixes that and also prevents that the following kernel crash can be triggered on the target: Call Trace: [<ffffffffa06b5350>] ? srpt_post_send+0xd0/0x140 [ib_srpt] [<ffffffff811bb595>] ? cpumask_next_and+0x35/0x50 [<ffffffff810e6296>] shmem_truncate_range+0x7a6/0xa50 [<ffffffffa0612ceb>] ? scst_get_buf_full+0x16b/0x270 [scst] [<ffffffffa069beb6>] vdisk_exec_unmap+0x1d6/0x4b0 [scst_vdisk] [<ffffffff813c0cb6>] ? _raw_spin_unlock+0x16/0x40 [<ffffffffa069dadc>] vdisk_do_job+0x5fc/0x950 [scst_vdisk] [<ffffffffa0605402>] scst_do_real_exec+0xb2/0x400 [scst] [<ffffffffa06076a7>] scst_exec+0xd7/0x240 [scst] [<ffffffffa06079b6>] scst_send_for_exec+0x1a6/0x2f0 [scst] [<ffffffffa06086f8>] scst_process_active_cmd+0x4f8/0x790 [scst] [<ffffffffa0608a29>] scst_do_job_active+0x99/0x170 [scst] [<ffffffffa060a3da>] scst_cmd_thread+0x15a/0x3b0 [scst] [<ffffffff81047470>] ? default_wake_function+0x0/0x20 [<ffffffffa060a280>] ? scst_cmd_thread+0x0/0x3b0 [scst] [<ffffffff8106dc26>] kthread+0x96/0xa0 [<ffffffff81003cd4>] kernel_thread_helper+0x4/0x10 [<ffffffff8103db01>] ? finish_task_switch+0x51/0xb0 [<ffffffff813c0c7c>] ? _raw_spin_unlock_irq+0x1c/0x40 [<ffffffff813c18b1>] ? restore_args+0x0/0x30 [<ffffffff8106db90>] ? kthread+0x0/0xa0 [<ffffffff81003cd0>] ? kernel_thread_helper+0x0/0x10 Invoking truncate_range() with an end len that is not page-size aligned triggers it. In other words, with a block size that is below PAGE_CACHE_SIZE some UNMAP commands could trigger a kernel bug. I think it's better to print an error message and to skip an UNMAP command instead of triggering a kernel oops. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3799 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1370,12 +1370,22 @@ static void vdisk_exec_unmap(struct scst_cmd *cmd, struct scst_vdisk_thr *thr)
|
||||
goto out_put;
|
||||
#endif
|
||||
} else {
|
||||
const int block_shift = virt_dev->block_shift;
|
||||
|
||||
/*
|
||||
* We are guaranteed by thin_provisioned flag
|
||||
* that truncate_range is not NULL.
|
||||
*/
|
||||
if (((start + len) << block_shift) &
|
||||
(PAGE_CACHE_SIZE - 1)) {
|
||||
PRINT_ERROR("Invalid UNMAP range [%llu, %llu); "
|
||||
"block size = %d", start, start + len,
|
||||
virt_dev->block_size);
|
||||
goto out_put;
|
||||
}
|
||||
inode->i_op->truncate_range(inode,
|
||||
start, start + len);
|
||||
start << block_shift,
|
||||
((start + len) << block_shift) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user