From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756716AbZBFJD0 (ORCPT ); Fri, 6 Feb 2009 04:03:26 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752461AbZBFJC6 (ORCPT ); Fri, 6 Feb 2009 04:02:58 -0500 Received: from smtp128.sbc.mail.sp1.yahoo.com ([69.147.65.187]:21493 "HELO smtp128.sbc.mail.sp1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751863AbZBFJC4 (ORCPT ); Fri, 6 Feb 2009 04:02:56 -0500 X-YMail-OSG: AD5EWPIVM1kXnc21EzmFgPwTzOevvTEQnnKZYRKZre6BfJTo3cVtspMo9BrDrC9KjIvEjrRjfJaqrG9eiCv877ju40fmc1rY42sKQ2xv.BoPNPGhBK3YZGqBlPh9D358RpSAFXShDLVwlXb0zg5cfCsAuU_zgWHgZ6F_b59wdSp6.BEofFogHCYXYf1QJFKGaq3lZphZbY_1Y9u41oa09zfYKmJ7sU6WVLXm7OP4j5hXIPvMNN4- X-Yahoo-Newman-Property: ymail-3 Subject: [PATCH] [Target_Core_Mod/ALUA]: Fix core_alua_free_*() locking logic From: "Nicholas A. Bellinger" To: LKML , linux-scsi Cc: Douglas Gilbert , James Bottomley , Andrew Morton , Mike Christie , FUJITA Tomonori , Hannes Reinecke , Christoph Hellwig , "Ross S. W. Walker" , Arne Redlich , Rafiu Fakunle Content-Type: text/plain Date: Fri, 06 Feb 2009 01:01:49 -0800 Message-Id: <1233910909.12375.375.camel@haakon2.linux-iscsi.org> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org >>From 1656e4dd155664a0b864c01a0f5d1fcdcddde4e7 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger 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 --- 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