Received: by 2002:a05:6358:a55:b0:ec:fcf4:3ecf with SMTP id 21csp3304169rwb; Mon, 16 Jan 2023 06:26:02 -0800 (PST) X-Google-Smtp-Source: AMrXdXtCrCUAHWB3kgP/jQGMUJWzME3IpeNFc1Z9tkhLHmhocBCs68r4hHSiBmHK4dQzUklPzrLi X-Received: by 2002:a05:6402:1801:b0:499:bf81:be6 with SMTP id g1-20020a056402180100b00499bf810be6mr23636495edy.37.1673879161923; Mon, 16 Jan 2023 06:26:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673879161; cv=none; d=google.com; s=arc-20160816; b=aF/ikLY2Hlt5Li7Rysj+DPW2AhJcTfHX7vyr9BiMj7l+s2FcmdsCMcQn5Ht0oFtUwl ErDQlCHlgIpd5KuHxvHvaqTvWe9D3wisXTiaNxcLmGx7aGOHaIXdF+5hr5Qffd5aYLC2 J8CFbpgmQbXZzqZuKOmuF4UMJ69lQ84LZ4A5GMYZ5ryLIdlZdNzhYUA9d8Q8QSPWgDS8 FQsaN8V8GQK9SL2KuVj80MZ4qdz5FJu9LL82wNbWR+uSCpYqKOz0Y2RUZ6WdM9Ej7zOD PHFAkZKk6fhiapM3xpcsaB7zl9nktHzOP3OBkczvqXkxKNsCiF0RYbX1jpeAtTuXMG5F vNtQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=rmotUwVGxwXiymu+4n3ysELx62/oZjgNGBW4mrNixPo=; b=uvbT/NMhL1VlS8+LOvVqT71jZabaCA9pTzukPlqeW+BbcZTihN/+91WXnmzp38I+me K68Kd33ZtSsWY2gUnssMUoR4nPbwOLRNz8PERCADbuhc7EsJwj00TE+2PkXOEuHwp9b+ MQfu6UhVCGu46wQPCvZBDQGCJLdDzDV09GTA4K05Ceamhck6iqokD+i59uMisMexHUyP JK6uWQiFvp9nOMS0TjwgaFdvWPF5bZz0RpltAqHU4i0boqUuPGEClKl2qvByuaQjD6l1 qaDj5cPuWAOVBUkDcoOi+DN0o7iMiGQ3TxvKMVbiLVR1kQlO5zu80oOcmBvtBNMfEFjH 6frQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YPaPr4Sm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j20-20020a05640211d400b0047db5ff4936si363449edw.490.2023.01.16.06.25.49; Mon, 16 Jan 2023 06:26:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YPaPr4Sm; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231799AbjAPOKR (ORCPT + 50 others); Mon, 16 Jan 2023 09:10:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58524 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232214AbjAPOIu (ORCPT ); Mon, 16 Jan 2023 09:08:50 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B984252AC; Mon, 16 Jan 2023 06:04:05 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 3B924B80F91; Mon, 16 Jan 2023 14:04:04 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ADEC5C433D2; Mon, 16 Jan 2023 14:04:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1673877842; bh=TWq0UVkpcd6iRnfaU4OztR0E5f/z5N/i0bQmqplI530=; h=From:To:Cc:Subject:Date:From; b=YPaPr4SmRHoxZury80TljE1oLIJiyGItGsCqN1WfryMzZogDXAyQwuETpFuK+Gqq4 OCniRpQcloWhPPHGRyIBVlFuXS1nafleOgwpHGYwtVJ9rdlSuUHCJXeFQzz1F2d2V8 isgI5fg7Kf3sfHU1sxugk1lPenWPJJvUcARCxsVg1ok/GczwrFJ3Yi634HhMtTq+oD DYhVW9vvsHQZBDjbH8PUAW7w78uT6bFnZ/Gppx/p19i7X3YnHoGKVP5+hUXxsPOvGq rJDnseNapCEU3HB0aqnvL9xTyaiL9rBXAzEBLZpEuV8HErTsn+fQxIgmlx4Yk/RdnG UnN3cNnjBj4Rg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Wenchao Hao , Mike Christie , Wu Bo , "Martin K . Petersen" , Sasha Levin , lduncan@suse.com, cleech@redhat.com, jejb@linux.ibm.com, open-iscsi@googlegroups.com, linux-scsi@vger.kernel.org Subject: [PATCH AUTOSEL 5.15 01/24] scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace Date: Mon, 16 Jan 2023 09:03:36 -0500 Message-Id: <20230116140359.115716-1-sashal@kernel.org> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wenchao Hao [ Upstream commit a3be19b91ea7121d388084e8c07f5b1b982eb40c ] It was observed that the kernel would potentially send ISCSI_KEVENT_UNBIND_SESSION multiple times. Introduce 'target_state' in iscsi_cls_session() to make sure session will send only one unbind session event. This introduces a regression wrt. the issue fixed in commit 13e60d3ba287 ("scsi: iscsi: Report unbind session event when the target has been removed"). If iscsid dies for any reason after sending an unbind session to kernel, once iscsid is restarted, the kernel's ISCSI_KEVENT_UNBIND_SESSION event is lost and userspace is then unable to logout. However, the session is actually in invalid state (its target_id is INVALID) so iscsid should not sync this session during restart. Consequently we need to check the session's target state during iscsid restart. If session is in unbound state, do not sync this session and perform session teardown. This is OK because once a session is unbound, we can not recover it any more (mainly because its target id is INVALID). Signed-off-by: Wenchao Hao Link: https://lore.kernel.org/r/20221126010752.231917-1-haowenchao@huawei.com Reviewed-by: Mike Christie Reviewed-by: Wu Bo Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/scsi_transport_iscsi.c | 50 ++++++++++++++++++++++++++--- include/scsi/scsi_transport_iscsi.h | 9 ++++++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index cc39cbef9d7f..4d23e5af20d3 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1679,6 +1679,13 @@ static const char *iscsi_session_state_name(int state) return name; } +static char *iscsi_session_target_state_name[] = { + [ISCSI_SESSION_TARGET_UNBOUND] = "UNBOUND", + [ISCSI_SESSION_TARGET_ALLOCATED] = "ALLOCATED", + [ISCSI_SESSION_TARGET_SCANNED] = "SCANNED", + [ISCSI_SESSION_TARGET_UNBINDING] = "UNBINDING", +}; + int iscsi_session_chkready(struct iscsi_cls_session *session) { int err; @@ -1807,9 +1814,13 @@ static int iscsi_user_scan_session(struct device *dev, void *data) if ((scan_data->channel == SCAN_WILD_CARD || scan_data->channel == 0) && (scan_data->id == SCAN_WILD_CARD || - scan_data->id == id)) + scan_data->id == id)) { scsi_scan_target(&session->dev, 0, id, scan_data->lun, scan_data->rescan); + spin_lock_irqsave(&session->lock, flags); + session->target_state = ISCSI_SESSION_TARGET_SCANNED; + spin_unlock_irqrestore(&session->lock, flags); + } } user_scan_exit: @@ -1998,31 +2009,41 @@ static void __iscsi_unbind_session(struct work_struct *work) struct iscsi_cls_host *ihost = shost->shost_data; unsigned long flags; unsigned int target_id; + bool remove_target = true; ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n"); /* Prevent new scans and make sure scanning is not in progress */ mutex_lock(&ihost->mutex); spin_lock_irqsave(&session->lock, flags); - if (session->target_id == ISCSI_MAX_TARGET) { + if (session->target_state == ISCSI_SESSION_TARGET_ALLOCATED) { + remove_target = false; + } else if (session->target_state != ISCSI_SESSION_TARGET_SCANNED) { spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); - goto unbind_session_exit; + ISCSI_DBG_TRANS_SESSION(session, + "Skipping target unbinding: Session is unbound/unbinding.\n"); + return; } + session->target_state = ISCSI_SESSION_TARGET_UNBINDING; target_id = session->target_id; session->target_id = ISCSI_MAX_TARGET; spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); - scsi_remove_target(&session->dev); + if (remove_target) + scsi_remove_target(&session->dev); if (session->ida_used) ida_simple_remove(&iscsi_sess_ida, target_id); -unbind_session_exit: iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); + + spin_lock_irqsave(&session->lock, flags); + session->target_state = ISCSI_SESSION_TARGET_UNBOUND; + spin_unlock_irqrestore(&session->lock, flags); } static void __iscsi_destroy_session(struct work_struct *work) @@ -2091,6 +2112,9 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) session->ida_used = true; } else session->target_id = target_id; + spin_lock_irqsave(&session->lock, flags); + session->target_state = ISCSI_SESSION_TARGET_ALLOCATED; + spin_unlock_irqrestore(&session->lock, flags); dev_set_name(&session->dev, "session%u", session->sid); err = device_add(&session->dev); @@ -4391,6 +4415,19 @@ iscsi_session_attr(def_taskmgmt_tmo, ISCSI_PARAM_DEF_TASKMGMT_TMO, 0); iscsi_session_attr(discovery_parent_idx, ISCSI_PARAM_DISCOVERY_PARENT_IDX, 0); iscsi_session_attr(discovery_parent_type, ISCSI_PARAM_DISCOVERY_PARENT_TYPE, 0); +static ssize_t +show_priv_session_target_state(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); + + return sysfs_emit(buf, "%s\n", + iscsi_session_target_state_name[session->target_state]); +} + +static ISCSI_CLASS_ATTR(priv_sess, target_state, S_IRUGO, + show_priv_session_target_state, NULL); + static ssize_t show_priv_session_state(struct device *dev, struct device_attribute *attr, char *buf) @@ -4493,6 +4530,7 @@ static struct attribute *iscsi_session_attrs[] = { &dev_attr_sess_boot_target.attr, &dev_attr_priv_sess_recovery_tmo.attr, &dev_attr_priv_sess_state.attr, + &dev_attr_priv_sess_target_state.attr, &dev_attr_priv_sess_creator.attr, &dev_attr_sess_chap_out_idx.attr, &dev_attr_sess_chap_in_idx.attr, @@ -4606,6 +4644,8 @@ static umode_t iscsi_session_attr_is_visible(struct kobject *kobj, return S_IRUGO | S_IWUSR; else if (attr == &dev_attr_priv_sess_state.attr) return S_IRUGO; + else if (attr == &dev_attr_priv_sess_target_state.attr) + return S_IRUGO; else if (attr == &dev_attr_priv_sess_creator.attr) return S_IRUGO; else if (attr == &dev_attr_priv_sess_target_id.attr) diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 0f2f149ad916..304ccf153928 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -236,6 +236,14 @@ enum { ISCSI_SESSION_FREE, }; +enum { + ISCSI_SESSION_TARGET_UNBOUND, + ISCSI_SESSION_TARGET_ALLOCATED, + ISCSI_SESSION_TARGET_SCANNED, + ISCSI_SESSION_TARGET_UNBINDING, + ISCSI_SESSION_TARGET_MAX, +}; + #define ISCSI_MAX_TARGET -1 struct iscsi_cls_session { @@ -262,6 +270,7 @@ struct iscsi_cls_session { */ pid_t creator; int state; + int target_state; /* session target bind state */ int sid; /* session id */ void *dd_data; /* LLD private data */ struct device dev; /* sysfs transport/container device */ -- 2.35.1