--- /dev/null
+From 035641b01e72af4f6c6cf22a4bdb5d7dfc4e8e8e Mon Sep 17 00:00:00 2001
+From: Peter Korsgaard <peter@korsgaard.com>
+Date: Wed, 16 Nov 2022 07:16:56 +0100
+Subject: dm init: add dm-mod.waitfor to wait for asynchronously probed block devices
+
+From: Peter Korsgaard <peter@korsgaard.com>
+
+commit 035641b01e72af4f6c6cf22a4bdb5d7dfc4e8e8e upstream.
+
+Just calling wait_for_device_probe() is not enough to ensure that
+asynchronously probed block devices are available (E.G. mmc, usb), so
+add a "dm-mod.waitfor=<device1>[,..,<deviceN>]" parameter to get
+dm-init to explicitly wait for specific block devices before
+initializing the tables with logic similar to the rootwait logic that
+was introduced with commit cc1ed7542c8c ("init: wait for
+asynchronously scanned block devices").
+
+E.G. with dm-verity on mmc using:
+dm-mod.waitfor="PARTLABEL=hash-a,PARTLABEL=root-a"
+
+[ 0.671671] device-mapper: init: waiting for all devices to be available before creating mapped devices
+[ 0.671679] device-mapper: init: waiting for device PARTLABEL=hash-a ...
+[ 0.710695] mmc0: new HS200 MMC card at address 0001
+[ 0.711158] mmcblk0: mmc0:0001 004GA0 3.69 GiB
+[ 0.715954] mmcblk0boot0: mmc0:0001 004GA0 partition 1 2.00 MiB
+[ 0.722085] mmcblk0boot1: mmc0:0001 004GA0 partition 2 2.00 MiB
+[ 0.728093] mmcblk0rpmb: mmc0:0001 004GA0 partition 3 512 KiB, chardev (249:0)
+[ 0.738274] mmcblk0: p1 p2 p3 p4 p5 p6 p7
+[ 0.751282] device-mapper: init: waiting for device PARTLABEL=root-a ...
+[ 0.751306] device-mapper: init: all devices available
+[ 0.751683] device-mapper: verity: sha256 using implementation "sha256-generic"
+[ 0.759344] device-mapper: ioctl: dm-0 (vroot) is ready
+[ 0.766540] VFS: Mounted root (squashfs filesystem) readonly on device 254:0.
+
+Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Cc: Mark-PK Tsai <mark-pk.tsai@mediatek.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/admin-guide/device-mapper/dm-init.rst | 8 +++++++
+ drivers/md/dm-init.c | 22 +++++++++++++++++++-
+ 2 files changed, 29 insertions(+), 1 deletion(-)
+
+--- a/Documentation/admin-guide/device-mapper/dm-init.rst
++++ b/Documentation/admin-guide/device-mapper/dm-init.rst
+@@ -123,3 +123,11 @@ Other examples (per target):
+ 0 1638400 verity 1 8:1 8:2 4096 4096 204800 1 sha256
+ fb1a5a0f00deb908d8b53cb270858975e76cf64105d412ce764225d53b8f3cfd
+ 51934789604d1b92399c52e7cb149d1b3a1b74bbbcb103b2a0aaacbed5c08584
++
++For setups using device-mapper on top of asynchronously probed block
++devices (MMC, USB, ..), it may be necessary to tell dm-init to
++explicitly wait for them to become available before setting up the
++device-mapper tables. This can be done with the "dm-mod.waitfor="
++module parameter, which takes a list of devices to wait for::
++
++ dm-mod.waitfor=<device1>[,..,<deviceN>]
+--- a/drivers/md/dm-init.c
++++ b/drivers/md/dm-init.c
+@@ -8,6 +8,7 @@
+ */
+
+ #include <linux/ctype.h>
++#include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/device-mapper.h>
+ #include <linux/init.h>
+@@ -18,12 +19,17 @@
+ #define DM_MAX_DEVICES 256
+ #define DM_MAX_TARGETS 256
+ #define DM_MAX_STR_SIZE 4096
++#define DM_MAX_WAITFOR 256
+
+ static char *create;
+
++static char *waitfor[DM_MAX_WAITFOR];
++
+ /*
+ * Format: dm-mod.create=<name>,<uuid>,<minor>,<flags>,<table>[,<table>+][;<name>,<uuid>,<minor>,<flags>,<table>[,<table>+]+]
+ * Table format: <start_sector> <num_sectors> <target_type> <target_args>
++ * Block devices to wait for to become available before setting up tables:
++ * dm-mod.waitfor=<device1>[,..,<deviceN>]
+ *
+ * See Documentation/admin-guide/device-mapper/dm-init.rst for dm-mod.create="..." format
+ * details.
+@@ -266,7 +272,7 @@ static int __init dm_init_init(void)
+ struct dm_device *dev;
+ LIST_HEAD(devices);
+ char *str;
+- int r;
++ int i, r;
+
+ if (!create)
+ return 0;
+@@ -286,6 +292,17 @@ static int __init dm_init_init(void)
+ DMINFO("waiting for all devices to be available before creating mapped devices");
+ wait_for_device_probe();
+
++ for (i = 0; i < ARRAY_SIZE(waitfor); i++) {
++ if (waitfor[i]) {
++ DMINFO("waiting for device %s ...", waitfor[i]);
++ while (!dm_get_dev_t(waitfor[i]))
++ msleep(5);
++ }
++ }
++
++ if (waitfor[0])
++ DMINFO("all devices available");
++
+ list_for_each_entry(dev, &devices, list) {
+ if (dm_early_create(&dev->dmi, dev->table,
+ dev->target_args_array))
+@@ -301,3 +318,6 @@ late_initcall(dm_init_init);
+
+ module_param(create, charp, 0);
+ MODULE_PARM_DESC(create, "Create a mapped device in early boot");
++
++module_param_array(waitfor, charp, NULL, 0);
++MODULE_PARM_DESC(waitfor, "Devices to wait for before setting up tables");
--- /dev/null
+From c847f4e203046a2c93d8a1cf0348315c0b655a60 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Fri, 19 May 2023 11:21:25 -0400
+Subject: fs: dlm: fix cleanup pending ops when interrupted
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit c847f4e203046a2c93d8a1cf0348315c0b655a60 upstream.
+
+Immediately clean up a posix lock request if it is interrupted
+while waiting for a result from user space (dlm_controld.) This
+largely reverts the recent commit b92a4e3f86b1 ("fs: dlm: change
+posix lock sigint handling"). That previous commit attempted
+to defer lock cleanup to the point in time when a result from
+user space arrived. The deferred approach was not reliable
+because some dlm plock ops may not receive replies.
+
+Cc: stable@vger.kernel.org
+Fixes: b92a4e3f86b1 ("fs: dlm: change posix lock sigint handling")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/plock.c | 25 ++++++-------------------
+ 1 file changed, 6 insertions(+), 19 deletions(-)
+
+--- a/fs/dlm/plock.c
++++ b/fs/dlm/plock.c
+@@ -29,8 +29,6 @@ struct plock_async_data {
+ struct plock_op {
+ struct list_head list;
+ int done;
+- /* if lock op got interrupted while waiting dlm_controld reply */
+- bool sigint;
+ struct dlm_plock_info info;
+ /* if set indicates async handling */
+ struct plock_async_data *data;
+@@ -166,12 +164,14 @@ int dlm_posix_lock(dlm_lockspace_t *lock
+ spin_unlock(&ops_lock);
+ goto do_lock_wait;
+ }
+-
+- op->sigint = true;
++ list_del(&op->list);
+ spin_unlock(&ops_lock);
++
+ log_debug(ls, "%s: wait interrupted %x %llx pid %d",
+ __func__, ls->ls_global_id,
+ (unsigned long long)number, op->info.pid);
++ do_unlock_close(&op->info);
++ dlm_release_plock_op(op);
+ goto out;
+ }
+
+@@ -433,19 +433,6 @@ static ssize_t dev_write(struct file *fi
+ if (iter->info.fsid == info.fsid &&
+ iter->info.number == info.number &&
+ iter->info.owner == info.owner) {
+- if (iter->sigint) {
+- list_del(&iter->list);
+- spin_unlock(&ops_lock);
+-
+- pr_debug("%s: sigint cleanup %x %llx pid %d",
+- __func__, iter->info.fsid,
+- (unsigned long long)iter->info.number,
+- iter->info.pid);
+- do_unlock_close(&iter->info);
+- memcpy(&iter->info, &info, sizeof(info));
+- dlm_release_plock_op(iter);
+- return count;
+- }
+ list_del_init(&iter->list);
+ memcpy(&iter->info, &info, sizeof(info));
+ if (iter->data)
+@@ -464,8 +451,8 @@ static ssize_t dev_write(struct file *fi
+ else
+ wake_up(&recv_wq);
+ } else
+- log_print("%s: no op %x %llx", __func__,
+- info.fsid, (unsigned long long)info.number);
++ pr_debug("%s: no op %x %llx", __func__,
++ info.fsid, (unsigned long long)info.number);
+ return count;
+ }
+
--- /dev/null
+From 57e2c2f2d94cfd551af91cedfa1af6d972487197 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Wed, 24 May 2023 12:02:04 -0400
+Subject: fs: dlm: fix mismatch of plock results from userspace
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 57e2c2f2d94cfd551af91cedfa1af6d972487197 upstream.
+
+When a waiting plock request (F_SETLKW) is sent to userspace
+for processing (dlm_controld), the result is returned at a
+later time. That result could be incorrectly matched to a
+different waiting request in cases where the owner field is
+the same (e.g. different threads in a process.) This is fixed
+by comparing all the properties in the request and reply.
+
+The results for non-waiting plock requests are now matched
+based on list order because the results are returned in the
+same order they were sent.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/plock.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 45 insertions(+), 13 deletions(-)
+
+--- a/fs/dlm/plock.c
++++ b/fs/dlm/plock.c
+@@ -394,7 +394,7 @@ static ssize_t dev_read(struct file *fil
+ if (op->info.flags & DLM_PLOCK_FL_CLOSE)
+ list_del(&op->list);
+ else
+- list_move(&op->list, &recv_list);
++ list_move_tail(&op->list, &recv_list);
+ memcpy(&info, &op->info, sizeof(info));
+ }
+ spin_unlock(&ops_lock);
+@@ -432,20 +432,52 @@ static ssize_t dev_write(struct file *fi
+ if (check_version(&info))
+ return -EINVAL;
+
++ /*
++ * The results for waiting ops (SETLKW) can be returned in any
++ * order, so match all fields to find the op. The results for
++ * non-waiting ops are returned in the order that they were sent
++ * to userspace, so match the result with the first non-waiting op.
++ */
+ spin_lock(&ops_lock);
+- list_for_each_entry(iter, &recv_list, list) {
+- if (iter->info.fsid == info.fsid &&
+- iter->info.number == info.number &&
+- iter->info.owner == info.owner) {
+- list_del_init(&iter->list);
+- memcpy(&iter->info, &info, sizeof(info));
+- if (iter->data)
+- do_callback = 1;
+- else
+- iter->done = 1;
+- op = iter;
+- break;
++ if (info.wait) {
++ list_for_each_entry(iter, &recv_list, list) {
++ if (iter->info.fsid == info.fsid &&
++ iter->info.number == info.number &&
++ iter->info.owner == info.owner &&
++ iter->info.pid == info.pid &&
++ iter->info.start == info.start &&
++ iter->info.end == info.end &&
++ iter->info.ex == info.ex &&
++ iter->info.wait) {
++ op = iter;
++ break;
++ }
+ }
++ } else {
++ list_for_each_entry(iter, &recv_list, list) {
++ if (!iter->info.wait) {
++ op = iter;
++ break;
++ }
++ }
++ }
++
++ if (op) {
++ /* Sanity check that op and info match. */
++ if (info.wait)
++ WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK);
++ else
++ WARN_ON(op->info.fsid != info.fsid ||
++ op->info.number != info.number ||
++ op->info.owner != info.owner ||
++ op->info.optype != info.optype);
++
++ list_del_init(&op->list);
++ memcpy(&op->info, &info, sizeof(info));
++ if (op->data)
++ do_callback = 1;
++ else
++ op->done = 1;
+ }
+ spin_unlock(&ops_lock);
+
--- /dev/null
+From 59e45c758ca1b9893ac923dd63536da946ac333b Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Fri, 19 May 2023 11:21:26 -0400
+Subject: fs: dlm: interrupt posix locks only when process is killed
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 59e45c758ca1b9893ac923dd63536da946ac333b upstream.
+
+If a posix lock request is waiting for a result from user space
+(dlm_controld), do not let it be interrupted unless the process
+is killed. This reverts commit a6b1533e9a57 ("dlm: make posix locks
+interruptible"). The problem with the interruptible change is
+that all locks were cleared on any signal interrupt. If a signal
+was received that did not terminate the process, the process
+could continue running after all its dlm posix locks had been
+cleared. A future patch will add cancelation to allow proper
+interruption.
+
+Cc: stable@vger.kernel.org
+Fixes: a6b1533e9a57 ("dlm: make posix locks interruptible")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/plock.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/dlm/plock.c
++++ b/fs/dlm/plock.c
+@@ -154,7 +154,7 @@ int dlm_posix_lock(dlm_lockspace_t *lock
+
+ send_op(op);
+
+- rv = wait_event_interruptible(recv_wq, (op->done != 0));
++ rv = wait_event_killable(recv_wq, (op->done != 0));
+ if (rv == -ERESTARTSYS) {
+ spin_lock(&ops_lock);
+ /* recheck under ops_lock if we got a done != 0,
--- /dev/null
+From 0f2b1cb89ccdbdcedf7143f4153a4da700a05f48 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Fri, 19 May 2023 11:21:27 -0400
+Subject: fs: dlm: make F_SETLK use unkillable wait_event
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 0f2b1cb89ccdbdcedf7143f4153a4da700a05f48 upstream.
+
+While a non-waiting posix lock request (F_SETLK) is waiting for
+user space processing (in dlm_controld), wait for that processing
+to complete with an unkillable wait_event(). This makes F_SETLK
+behave the same way for F_RDLCK, F_WRLCK and F_UNLCK. F_SETLKW
+continues to use wait_event_killable().
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/plock.c | 38 +++++++++++++++++++++-----------------
+ 1 file changed, 21 insertions(+), 17 deletions(-)
+
+--- a/fs/dlm/plock.c
++++ b/fs/dlm/plock.c
+@@ -154,25 +154,29 @@ int dlm_posix_lock(dlm_lockspace_t *lock
+
+ send_op(op);
+
+- rv = wait_event_killable(recv_wq, (op->done != 0));
+- if (rv == -ERESTARTSYS) {
+- spin_lock(&ops_lock);
+- /* recheck under ops_lock if we got a done != 0,
+- * if so this interrupt case should be ignored
+- */
+- if (op->done != 0) {
++ if (op->info.wait) {
++ rv = wait_event_killable(recv_wq, (op->done != 0));
++ if (rv == -ERESTARTSYS) {
++ spin_lock(&ops_lock);
++ /* recheck under ops_lock if we got a done != 0,
++ * if so this interrupt case should be ignored
++ */
++ if (op->done != 0) {
++ spin_unlock(&ops_lock);
++ goto do_lock_wait;
++ }
++ list_del(&op->list);
+ spin_unlock(&ops_lock);
+- goto do_lock_wait;
+- }
+- list_del(&op->list);
+- spin_unlock(&ops_lock);
+
+- log_debug(ls, "%s: wait interrupted %x %llx pid %d",
+- __func__, ls->ls_global_id,
+- (unsigned long long)number, op->info.pid);
+- do_unlock_close(&op->info);
+- dlm_release_plock_op(op);
+- goto out;
++ log_debug(ls, "%s: wait interrupted %x %llx pid %d",
++ __func__, ls->ls_global_id,
++ (unsigned long long)number, op->info.pid);
++ do_unlock_close(&op->info);
++ dlm_release_plock_op(op);
++ goto out;
++ }
++ } else {
++ wait_event(recv_wq, (op->done != 0));
+ }
+
+ do_lock_wait:
--- /dev/null
+From 92655fbda5c05950a411eaabc19e025e86e2a291 Mon Sep 17 00:00:00 2001
+From: Alexander Aring <aahringo@redhat.com>
+Date: Fri, 19 May 2023 11:21:24 -0400
+Subject: fs: dlm: return positive pid value for F_GETLK
+
+From: Alexander Aring <aahringo@redhat.com>
+
+commit 92655fbda5c05950a411eaabc19e025e86e2a291 upstream.
+
+The GETLK pid values have all been negated since commit 9d5b86ac13c5
+("fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks").
+Revert this for local pids, and leave in place negative pids for remote
+owners.
+
+Cc: stable@vger.kernel.org
+Fixes: 9d5b86ac13c5 ("fs/locks: Remove fl_nspid and use fs-specific l_pid for remote locks")
+Signed-off-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: David Teigland <teigland@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/dlm/plock.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/dlm/plock.c
++++ b/fs/dlm/plock.c
+@@ -359,7 +359,9 @@ int dlm_posix_get(dlm_lockspace_t *locks
+ locks_init_lock(fl);
+ fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK;
+ fl->fl_flags = FL_POSIX;
+- fl->fl_pid = -op->info.pid;
++ fl->fl_pid = op->info.pid;
++ if (op->info.nodeid != dlm_our_nodeid())
++ fl->fl_pid = -fl->fl_pid;
+ fl->fl_start = op->info.start;
+ fl->fl_end = op->info.end;
+ rv = 0;
--- /dev/null
+From 97f975823f8196d970bd795087b514271214677a Mon Sep 17 00:00:00 2001
+From: Justin Tee <justin.tee@broadcom.com>
+Date: Mon, 17 Apr 2023 12:15:53 -0700
+Subject: scsi: lpfc: Fix double free in lpfc_cmpl_els_logo_acc() caused by lpfc_nlp_not_used()
+
+From: Justin Tee <justin.tee@broadcom.com>
+
+commit 97f975823f8196d970bd795087b514271214677a upstream.
+
+Smatch detected a double free path because lpfc_nlp_not_used() releases an
+ndlp object before reaching lpfc_nlp_put() at the end of
+lpfc_cmpl_els_logo_acc().
+
+Remove the outdated lpfc_nlp_not_used() routine. In
+lpfc_mbx_cmpl_ns_reg_login(), replace the call with lpfc_nlp_put(). In
+lpfc_cmpl_els_logo_acc(), replace the call with lpfc_unreg_rpi() and keep
+the lpfc_nlp_put() at the end of the routine. If ndlp's rpi was
+registered, then lpfc_unreg_rpi()'s completion routine performs the final
+ndlp clean up after lpfc_nlp_put() is called from lpfc_cmpl_els_logo_acc().
+Otherwise if ndlp has no rpi registered, the lpfc_nlp_put() at the end of
+lpfc_cmpl_els_logo_acc() is the final ndlp clean up.
+
+Fixes: 4430f7fd09ec ("scsi: lpfc: Rework locations of ndlp reference taking")
+Cc: <stable@vger.kernel.org> # v5.11+
+Reported-by: Dan Carpenter <error27@gmail.com>
+Link: https://lore.kernel.org/all/Y3OefhyyJNKH%2Fiaf@kili/
+Signed-off-by: Justin Tee <justin.tee@broadcom.com>
+Link: https://lore.kernel.org/r/20230417191558.83100-3-justintee8345@gmail.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/lpfc/lpfc_crtn.h | 1 -
+ drivers/scsi/lpfc/lpfc_els.c | 30 +++++++-----------------------
+ drivers/scsi/lpfc/lpfc_hbadisc.c | 24 +++---------------------
+ 3 files changed, 10 insertions(+), 45 deletions(-)
+
+--- a/drivers/scsi/lpfc/lpfc_crtn.h
++++ b/drivers/scsi/lpfc/lpfc_crtn.h
+@@ -134,7 +134,6 @@ void lpfc_check_nlp_post_devloss(struct
+ struct lpfc_nodelist *ndlp);
+ void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+ struct lpfc_iocbq *rspiocb);
+-int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp);
+ struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t);
+ void lpfc_disc_list_loopmap(struct lpfc_vport *);
+ void lpfc_disc_start(struct lpfc_vport *);
+--- a/drivers/scsi/lpfc/lpfc_els.c
++++ b/drivers/scsi/lpfc/lpfc_els.c
+@@ -5150,14 +5150,9 @@ lpfc_els_free_iocb(struct lpfc_hba *phba
+ *
+ * This routine is the completion callback function to the Logout (LOGO)
+ * Accept (ACC) Response ELS command. This routine is invoked to indicate
+- * the completion of the LOGO process. It invokes the lpfc_nlp_not_used() to
+- * release the ndlp if it has the last reference remaining (reference count
+- * is 1). If succeeded (meaning ndlp released), it sets the iocb ndlp
+- * field to NULL to inform the following lpfc_els_free_iocb() routine no
+- * ndlp reference count needs to be decremented. Otherwise, the ndlp
+- * reference use-count shall be decremented by the lpfc_els_free_iocb()
+- * routine. Finally, the lpfc_els_free_iocb() is invoked to release the
+- * IOCB data structure.
++ * the completion of the LOGO process. If the node has transitioned to NPR,
++ * this routine unregisters the RPI if it is still registered. The
++ * lpfc_els_free_iocb() is invoked to release the IOCB data structure.
+ **/
+ static void
+ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
+@@ -5198,19 +5193,9 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
+ (ndlp->nlp_last_elscmd == ELS_CMD_PLOGI))
+ goto out;
+
+- /* NPort Recovery mode or node is just allocated */
+- if (!lpfc_nlp_not_used(ndlp)) {
+- /* A LOGO is completing and the node is in NPR state.
+- * Just unregister the RPI because the node is still
+- * required.
+- */
++ if (ndlp->nlp_flag & NLP_RPI_REGISTERED)
+ lpfc_unreg_rpi(vport, ndlp);
+- } else {
+- /* Indicate the node has already released, should
+- * not reference to it from within lpfc_els_free_iocb.
+- */
+- cmdiocb->ndlp = NULL;
+- }
++
+ }
+ out:
+ /*
+@@ -5230,9 +5215,8 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
+ * RPI (Remote Port Index) mailbox command to the @phba. It simply releases
+ * the associated lpfc Direct Memory Access (DMA) buffer back to the pool and
+ * decrements the ndlp reference count held for this completion callback
+- * function. After that, it invokes the lpfc_nlp_not_used() to check
+- * whether there is only one reference left on the ndlp. If so, it will
+- * perform one more decrement and trigger the release of the ndlp.
++ * function. After that, it invokes the lpfc_drop_node to check
++ * whether it is appropriate to release the node.
+ **/
+ void
+ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
+@@ -4332,13 +4332,14 @@ out:
+
+ /* If the node is not registered with the scsi or nvme
+ * transport, remove the fabric node. The failed reg_login
+- * is terminal.
++ * is terminal and forces the removal of the last node
++ * reference.
+ */
+ if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) {
+ spin_lock_irq(&ndlp->lock);
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+ spin_unlock_irq(&ndlp->lock);
+- lpfc_nlp_not_used(ndlp);
++ lpfc_nlp_put(ndlp);
+ }
+
+ if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
+@@ -6703,25 +6704,6 @@ lpfc_nlp_put(struct lpfc_nodelist *ndlp)
+ return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0;
+ }
+
+-/* This routine free's the specified nodelist if it is not in use
+- * by any other discovery thread. This routine returns 1 if the
+- * ndlp has been freed. A return value of 0 indicates the ndlp is
+- * not yet been released.
+- */
+-int
+-lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
+-{
+- lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
+- "node not used: did:x%x flg:x%x refcnt:x%x",
+- ndlp->nlp_DID, ndlp->nlp_flag,
+- kref_read(&ndlp->kref));
+-
+- if (kref_read(&ndlp->kref) == 1)
+- if (lpfc_nlp_put(ndlp))
+- return 1;
+- return 0;
+-}
+-
+ /**
+ * lpfc_fcf_inuse - Check if FCF can be unregistered.
+ * @phba: Pointer to hba context object.
misc-pci_endpoint_test-re-init-completion-for-every-test.patch
mfd-pm8008-fix-module-autoloading.patch
md-raid0-add-discard-support-for-the-original-layout.patch
+dm-init-add-dm-mod.waitfor-to-wait-for-asynchronously-probed-block-devices.patch
+fs-dlm-return-positive-pid-value-for-f_getlk.patch
+fs-dlm-fix-cleanup-pending-ops-when-interrupted.patch
+fs-dlm-interrupt-posix-locks-only-when-process-is-killed.patch
+fs-dlm-make-f_setlk-use-unkillable-wait_event.patch
+fs-dlm-fix-mismatch-of-plock-results-from-userspace.patch
+scsi-lpfc-fix-double-free-in-lpfc_cmpl_els_logo_acc-caused-by-lpfc_nlp_not_used.patch