Skip to content

Commit 4cbec7e

Browse files
mikechristiemartinkpetersen
authored andcommitted
scsi: target: Fix unmap setup during configuration
This issue was found and also debugged by Carl Lei <me@xecycle.info>. If the device is not enabled, iblock/file will have not setup their se_device to bdev/file mappings. If a user tries to config the unmap settings at this time, we will then crash trying to access a NULL pointer where the bdev/file should be. This patch adds a check to make sure the device is configured before we try to call the configure_unmap callout. Fixes: 34bd1dc ("scsi: target: Detect UNMAP support post configuration") Reported-by: Carl Lei <me@xecycle.info> Signed-off-by: Mike Christie <michael.christie@oracle.com> Link: https://lore.kernel.org/r/20240209215247.5213-1-michael.christie@oracle.com Reviewed-by: Maurizio Lombardi <mlombard@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 17e94b2 commit 4cbec7e

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

drivers/target/target_core_configfs.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,29 @@ static ssize_t emulate_tas_store(struct config_item *item,
759759
return count;
760760
}
761761

762+
static int target_try_configure_unmap(struct se_device *dev,
763+
const char *config_opt)
764+
{
765+
if (!dev->transport->configure_unmap) {
766+
pr_err("Generic Block Discard not supported\n");
767+
return -ENOSYS;
768+
}
769+
770+
if (!target_dev_configured(dev)) {
771+
pr_err("Generic Block Discard setup for %s requires device to be configured\n",
772+
config_opt);
773+
return -ENODEV;
774+
}
775+
776+
if (!dev->transport->configure_unmap(dev)) {
777+
pr_err("Generic Block Discard setup for %s failed\n",
778+
config_opt);
779+
return -ENOSYS;
780+
}
781+
782+
return 0;
783+
}
784+
762785
static ssize_t emulate_tpu_store(struct config_item *item,
763786
const char *page, size_t count)
764787
{
@@ -776,11 +799,9 @@ static ssize_t emulate_tpu_store(struct config_item *item,
776799
* Discard supported is detected iblock_create_virtdevice().
777800
*/
778801
if (flag && !da->max_unmap_block_desc_count) {
779-
if (!dev->transport->configure_unmap ||
780-
!dev->transport->configure_unmap(dev)) {
781-
pr_err("Generic Block Discard not supported\n");
782-
return -ENOSYS;
783-
}
802+
ret = target_try_configure_unmap(dev, "emulate_tpu");
803+
if (ret)
804+
return ret;
784805
}
785806

786807
da->emulate_tpu = flag;
@@ -806,11 +827,9 @@ static ssize_t emulate_tpws_store(struct config_item *item,
806827
* Discard supported is detected iblock_create_virtdevice().
807828
*/
808829
if (flag && !da->max_unmap_block_desc_count) {
809-
if (!dev->transport->configure_unmap ||
810-
!dev->transport->configure_unmap(dev)) {
811-
pr_err("Generic Block Discard not supported\n");
812-
return -ENOSYS;
813-
}
830+
ret = target_try_configure_unmap(dev, "emulate_tpws");
831+
if (ret)
832+
return ret;
814833
}
815834

816835
da->emulate_tpws = flag;
@@ -1022,12 +1041,9 @@ static ssize_t unmap_zeroes_data_store(struct config_item *item,
10221041
* Discard supported is detected iblock_configure_device().
10231042
*/
10241043
if (flag && !da->max_unmap_block_desc_count) {
1025-
if (!dev->transport->configure_unmap ||
1026-
!dev->transport->configure_unmap(dev)) {
1027-
pr_err("dev[%p]: Thin Provisioning LBPRZ will not be set because max_unmap_block_desc_count is zero\n",
1028-
da->da_dev);
1029-
return -ENOSYS;
1030-
}
1044+
ret = target_try_configure_unmap(dev, "unmap_zeroes_data");
1045+
if (ret)
1046+
return ret;
10311047
}
10321048
da->unmap_zeroes_data = flag;
10331049
pr_debug("dev[%p]: SE Device Thin Provisioning LBPRZ bit: %d\n",

0 commit comments

Comments
 (0)