[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <5f637569-36af-a8d0-e378-b27a63f08501@gmail.com>
Date: Sat, 20 May 2023 02:26:14 +0200
From: Grzegorz Uriasz <gorbak25@...il.com>
To: "Martin K. Petersen" <martin.petersen@...cle.com>,
linux-scsi@...r.kernel.org, target-devel@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: dutkahugo@...il.com
Subject: [PATCH] scsi: target: Fix data corruption under concurrent target
configuration
This fixes data corruptions arising from concurrent enabling of a target
devices. When multiple enable calls are made concurrently then it is
possible for the target device to be set up twice which results in a
kernel BUG.
Introduces a per target device mutex for serializing enable requests.
Signed-off-by: Grzegorz Uriasz <gorbak25@...il.com>
---
drivers/target/target_core_device.c | 17 +++++++++++++----
include/target/target_core_base.h | 1 +
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/target/target_core_device.c
b/drivers/target/target_core_device.c
index 90f3f4926172..6d8fb962c780 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -742,6 +742,7 @@ struct se_device *target_alloc_device(struct se_hba
*hba, const char *name)
INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work);
mutex_init(&dev->lun_reset_mutex);
+ mutex_init(&dev->configure_mutex);
dev->t10_wwn.t10_dev = dev;
/*
@@ -904,10 +905,15 @@ int target_configure_device(struct se_device *dev)
struct se_hba *hba = dev->se_hba;
int ret, id;
+ ret = mutex_lock_interruptible(&dev->configure_mutex);
+ if (ret)
+ return ret;
+
if (target_dev_configured(dev)) {
pr_err("se_dev->se_dev_ptr already set for storage"
" object\n");
- return -EEXIST;
+ ret = -EEXIST;
+ goto out_release_mutex;
}
/*
@@ -923,7 +929,7 @@ int target_configure_device(struct se_device *dev)
mutex_unlock(&device_mutex);
if (id < 0) {
ret = -ENOMEM;
- goto out;
+ goto out_release_vpd;
}
dev->dev_index = id;
@@ -969,7 +975,8 @@ int target_configure_device(struct se_device *dev)
dev->dev_flags |= DF_CONFIGURED;
- return 0;
+ ret = 0;
+ goto out_release_mutex;
out_destroy_device:
dev->transport->destroy_device(dev);
@@ -977,8 +984,10 @@ int target_configure_device(struct se_device *dev)
mutex_lock(&device_mutex);
idr_remove(&devices_idr, dev->dev_index);
mutex_unlock(&device_mutex);
-out:
+out_release_vpd:
se_release_vpd_for_dev(dev);
+out_release_mutex:
+ mutex_unlock(&dev->configure_mutex);
return ret;
}
diff --git a/include/target/target_core_base.h
b/include/target/target_core_base.h
index 5f8e96f1516f..b3f9bd641688 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -869,6 +869,7 @@ struct se_device {
int queue_cnt;
struct se_device_queue *queues;
struct mutex lun_reset_mutex;
+ struct mutex configure_mutex;
};
struct target_opcode_descriptor {
--
2.40.0
View attachment "DMESG_LOGS" of type "text/plain" (5606 bytes)
Powered by blists - more mailing lists