[PATCH] [Target_Core_Mod/ALUA]: Fix core_alua_free_*() locking logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 1656e4dd155664a0b864c01a0f5d1fcdcddde4e7 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Fri, 6 Feb 2009 00:55:06 -0800
Subject: [PATCH] [Target_Core_Mod/ALUA]: Fix core_alua_free_*() locking logic

This patch releases the lu_gp->lu_gp_ref_lock in core_alua_free_lu_gp()
and tg_pt_gp->tg_pt_gp_ref_lock in core_alua_free_tg_pt_gp() before
clearing se_device_t->dev_alua_lu_gp and se_port_t->sep_alua_tg_pt_gp
pointers respectively.

It also moves list_del() in core_alua_free_lu_gp() and
core_alua_free_tg_pt_gp() to before the "loop through group list and release".
This is to prevent any concurrent ALUA association attempts by other
userspace processes into Target_Core_Mod/ConfigFS.

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/lio-core/target_core_alua.c |   42 ++++++++++++++++++++++++++--------
 1 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/drivers/lio-core/target_core_alua.c b/drivers/lio-core/target_core_alua.c
index b5f5d66..722be1a 100644
--- a/drivers/lio-core/target_core_alua.c
+++ b/drivers/lio-core/target_core_alua.c
@@ -166,21 +166,32 @@ again:
 extern void core_alua_free_lu_gp (t10_alua_lu_gp_t *lu_gp)
 {
 	se_device_t *dev, *dev_tmp;
+	/*
+	 * Once we have reached this point, config_item_put() has
+	 * already been called from target_core_alua_drop_lu_gp().
+	 * 
+	 * Here, we remove the *lu_gp from the global list so that
+	 * no associations can be made while we are releasing
+	 * t10_alua_lu_gp_t.
+	 */
+	spin_lock(&se_global->lu_gps_lock);
+	list_del(&lu_gp->lu_gp_list);
+	se_global->alua_lu_gps_count--;
+	spin_unlock(&se_global->lu_gps_lock);
 
 	spin_lock(&lu_gp->lu_gp_ref_lock);
 	list_for_each_entry_safe(dev, dev_tmp, &lu_gp->lu_gp_ref_list, dev_lu_gp_list) {
 		list_del(&dev->dev_lu_gp_list);	
+		spin_unlock(&lu_gp->lu_gp_ref_lock);
+
 		spin_lock(&dev->dev_alua_lock);
 		dev->dev_alua_lu_gp = NULL;
 		spin_unlock(&dev->dev_alua_lock);
+		
+		spin_lock(&lu_gp->lu_gp_ref_lock);
 	}
 	spin_unlock(&lu_gp->lu_gp_ref_lock);
 
-	spin_lock(&se_global->lu_gps_lock);
-	list_del(&lu_gp->lu_gp_list);
-	se_global->alua_lu_gps_count--;
-	spin_unlock(&se_global->lu_gps_lock);
-
 	kmem_cache_free(t10_alua_lu_gp_cache, lu_gp);
 	return;
 }
@@ -305,22 +316,33 @@ again:
 extern void core_alua_free_tg_pt_gp (t10_alua_tg_pt_gp_t *tg_pt_gp)
 {
 	se_port_t *port, *port_tmp;
+	/*
+	 * Once we have reached this point, config_item_put() has already
+	 * been called from target_core_alua_drop_tg_pt_gp().
+	 *
+	 * Here we remove *tg_pt_gp from the global list so that
+	 * no assications *OR* explict ALUA via SET_TARGET_PORT_GROUPS
+	 * can be made while we are releasing t10_alua_tg_pt_gp_t.
+	 */
+	spin_lock(&se_global->tg_pt_gps_lock);
+	list_del(&tg_pt_gp->tg_pt_gp_list);
+	se_global->alua_tg_pt_gps_counter--;
+	spin_unlock(&se_global->tg_pt_gps_lock);
 
 	spin_lock(&tg_pt_gp->tg_pt_gp_ref_lock);
 	list_for_each_entry_safe(port, port_tmp, &tg_pt_gp->tg_pt_gp_ref_list,
 			sep_tg_pt_gp_list) {
 		list_del(&port->sep_tg_pt_gp_list);
+		spin_unlock(&tg_pt_gp->tg_pt_gp_ref_lock);
+
 		spin_lock(&port->sep_alua_lock);
 		port->sep_alua_tg_pt_gp = NULL;
 		spin_unlock(&port->sep_alua_lock);
+
+		spin_lock(&tg_pt_gp->tg_pt_gp_ref_lock);
 	}
 	spin_unlock(&tg_pt_gp->tg_pt_gp_ref_lock);
 
-	spin_lock(&se_global->tg_pt_gps_lock);
-	list_del(&tg_pt_gp->tg_pt_gp_list);
-	se_global->alua_tg_pt_gps_counter--;
-	spin_unlock(&se_global->tg_pt_gps_lock);
-
 	kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp);
 	return;
 }
-- 
1.5.4.1



--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux