--- /dev/null
+From a34315e8c03491d93e66bd4e9138a5eb12ba857a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 14:01:59 +0000
+Subject: cifs: Fix non-availability of dedup breaking generic/304
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 691a41d8da4b34fe72f09393505f55f28a8f34ec ]
+
+Deduplication isn't supported on cifs, but cifs doesn't reject it, instead
+treating it as extent duplication/cloning. This can cause generic/304 to go
+silly and run for hours on end.
+
+Fix cifs to indicate EOPNOTSUPP if REMAP_FILE_DEDUP is set in
+->remap_file_range().
+
+Note that it's unclear whether or not commit b073a08016a1 is meant to cause
+cifs to return an error if REMAP_FILE_DEDUP.
+
+Fixes: b073a08016a1 ("cifs: fix that return -EINVAL when do dedupe operation")
+Cc: stable@vger.kernel.org
+Suggested-by: Dave Chinner <david@fromorbit.com>
+cc: Xiaoli Feng <fengxiaoli0714@gmail.com>
+cc: Shyam Prasad N <nspmangalore@gmail.com>
+cc: Rohith Surabattula <rohiths.msft@gmail.com>
+cc: Jeff Layton <jlayton@kernel.org>
+cc: Darrick Wong <darrick.wong@oracle.com>
+cc: fstests@vger.kernel.org
+cc: linux-cifs@vger.kernel.org
+cc: linux-fsdevel@vger.kernel.org
+Link: https://lore.kernel.org/r/3876191.1701555260@warthog.procyon.org.uk/
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/cifsfs.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index af688e39f31ac..9bbead15a0287 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -1144,7 +1144,9 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
+ unsigned int xid;
+ int rc;
+
+- if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
++ if (remap_flags & REMAP_FILE_DEDUP)
++ return -EOPNOTSUPP;
++ if (remap_flags & ~REMAP_FILE_ADVISORY)
+ return -EINVAL;
+
+ cifs_dbg(FYI, "clone range\n");
+--
+2.42.0
+
--- /dev/null
+From e28b969f6e88a2541bdff980382df9ba84325a97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Nov 2023 20:19:32 +0530
+Subject: devcoredump: Send uevent once devcd is ready
+
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+
+[ Upstream commit af54d778a03853801d681c98c0c2a6c316ef9ca7 ]
+
+dev_coredumpm() creates a devcoredump device and adds it
+to the core kernel framework which eventually end up
+sending uevent to the user space and later creates a
+symbolic link to the failed device. An application
+running in userspace may be interested in this symbolic
+link to get the name of the failed device.
+
+In a issue scenario, once uevent sent to the user space
+it start reading '/sys/class/devcoredump/devcdX/failing_device'
+to get the actual name of the device which might not been
+created and it is in its path of creation.
+
+To fix this, suppress sending uevent till the failing device
+symbolic link gets created and send uevent once symbolic
+link is created successfully.
+
+Fixes: 833c95456a70 ("device coredump: add new device coredump class")
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/1700232572-25823-1-git-send-email-quic_mojha@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/devcoredump.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c
+index 1c06781f71148..f3bd9f104bd12 100644
+--- a/drivers/base/devcoredump.c
++++ b/drivers/base/devcoredump.c
+@@ -363,6 +363,7 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+ devcd->devcd_dev.class = &devcd_class;
+
+ mutex_lock(&devcd->mutex);
++ dev_set_uevent_suppress(&devcd->devcd_dev, true);
+ if (device_add(&devcd->devcd_dev))
+ goto put_device;
+
+@@ -377,6 +378,8 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+ "devcoredump"))
+ dev_warn(dev, "devcoredump create_link failed\n");
+
++ dev_set_uevent_suppress(&devcd->devcd_dev, false);
++ kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD);
+ INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
+ schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);
+ mutex_unlock(&devcd->mutex);
+--
+2.42.0
+
--- /dev/null
+From 7ee0e7dc6b38e7aee51a5a007646c12985aa1b51 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Sep 2022 18:20:24 +0530
+Subject: devcoredump : Serialize devcd_del work
+
+From: Mukesh Ojha <quic_mojha@quicinc.com>
+
+[ Upstream commit 01daccf748323dfc61112f474cf2ba81015446b0 ]
+
+In following scenario(diagram), when one thread X running dev_coredumpm()
+adds devcd device to the framework which sends uevent notification to
+userspace and another thread Y reads this uevent and call to
+devcd_data_write() which eventually try to delete the queued timer that
+is not initialized/queued yet.
+
+So, debug object reports some warning and in the meantime, timer is
+initialized and queued from X path. and from Y path, it gets reinitialized
+again and timer->entry.pprev=NULL and try_to_grab_pending() stucks.
+
+To fix this, introduce mutex and a boolean flag to serialize the behaviour.
+
+ cpu0(X) cpu1(Y)
+
+ dev_coredump() uevent sent to user space
+ device_add() ======================> user space process Y reads the
+ uevents writes to devcd fd
+ which results into writes to
+
+ devcd_data_write()
+ mod_delayed_work()
+ try_to_grab_pending()
+ del_timer()
+ debug_assert_init()
+ INIT_DELAYED_WORK()
+ schedule_delayed_work()
+ debug_object_fixup()
+ timer_fixup_assert_init()
+ timer_setup()
+ do_init_timer()
+ /*
+ Above call reinitializes
+ the timer to
+ timer->entry.pprev=NULL
+ and this will be checked
+ later in timer_pending() call.
+ */
+ timer_pending()
+ !hlist_unhashed_lockless(&timer->entry)
+ !h->pprev
+ /*
+ del_timer() checks h->pprev and finds
+ it to be NULL due to which
+ try_to_grab_pending() stucks.
+ */
+
+Link: https://lore.kernel.org/lkml/2e1f81e2-428c-f11f-ce92-eb11048cb271@quicinc.com/
+Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
+Link: https://lore.kernel.org/r/1663073424-13663-1-git-send-email-quic_mojha@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: af54d778a038 ("devcoredump: Send uevent once devcd is ready")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/devcoredump.c | 83 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c
+index f4d794d6bb859..1c06781f71148 100644
+--- a/drivers/base/devcoredump.c
++++ b/drivers/base/devcoredump.c
+@@ -25,6 +25,47 @@ struct devcd_entry {
+ struct device devcd_dev;
+ void *data;
+ size_t datalen;
++ /*
++ * Here, mutex is required to serialize the calls to del_wk work between
++ * user/kernel space which happens when devcd is added with device_add()
++ * and that sends uevent to user space. User space reads the uevents,
++ * and calls to devcd_data_write() which try to modify the work which is
++ * not even initialized/queued from devcoredump.
++ *
++ *
++ *
++ * cpu0(X) cpu1(Y)
++ *
++ * dev_coredump() uevent sent to user space
++ * device_add() ======================> user space process Y reads the
++ * uevents writes to devcd fd
++ * which results into writes to
++ *
++ * devcd_data_write()
++ * mod_delayed_work()
++ * try_to_grab_pending()
++ * del_timer()
++ * debug_assert_init()
++ * INIT_DELAYED_WORK()
++ * schedule_delayed_work()
++ *
++ *
++ * Also, mutex alone would not be enough to avoid scheduling of
++ * del_wk work after it get flush from a call to devcd_free()
++ * mentioned as below.
++ *
++ * disabled_store()
++ * devcd_free()
++ * mutex_lock() devcd_data_write()
++ * flush_delayed_work()
++ * mutex_unlock()
++ * mutex_lock()
++ * mod_delayed_work()
++ * mutex_unlock()
++ * So, delete_work flag is required.
++ */
++ struct mutex mutex;
++ bool delete_work;
+ struct module *owner;
+ ssize_t (*read)(char *buffer, loff_t offset, size_t count,
+ void *data, size_t datalen);
+@@ -84,7 +125,12 @@ static ssize_t devcd_data_write(struct file *filp, struct kobject *kobj,
+ struct device *dev = kobj_to_dev(kobj);
+ struct devcd_entry *devcd = dev_to_devcd(dev);
+
+- mod_delayed_work(system_wq, &devcd->del_wk, 0);
++ mutex_lock(&devcd->mutex);
++ if (!devcd->delete_work) {
++ devcd->delete_work = true;
++ mod_delayed_work(system_wq, &devcd->del_wk, 0);
++ }
++ mutex_unlock(&devcd->mutex);
+
+ return count;
+ }
+@@ -112,7 +158,12 @@ static int devcd_free(struct device *dev, void *data)
+ {
+ struct devcd_entry *devcd = dev_to_devcd(dev);
+
++ mutex_lock(&devcd->mutex);
++ if (!devcd->delete_work)
++ devcd->delete_work = true;
++
+ flush_delayed_work(&devcd->del_wk);
++ mutex_unlock(&devcd->mutex);
+ return 0;
+ }
+
+@@ -122,6 +173,30 @@ static ssize_t disabled_show(struct class *class, struct class_attribute *attr,
+ return sysfs_emit(buf, "%d\n", devcd_disabled);
+ }
+
++/*
++ *
++ * disabled_store() worker()
++ * class_for_each_device(&devcd_class,
++ * NULL, NULL, devcd_free)
++ * ...
++ * ...
++ * while ((dev = class_dev_iter_next(&iter))
++ * devcd_del()
++ * device_del()
++ * put_device() <- last reference
++ * error = fn(dev, data) devcd_dev_release()
++ * devcd_free(dev, data) kfree(devcd)
++ * mutex_lock(&devcd->mutex);
++ *
++ *
++ * In the above diagram, It looks like disabled_store() would be racing with parallely
++ * running devcd_del() and result in memory abort while acquiring devcd->mutex which
++ * is called after kfree of devcd memory after dropping its last reference with
++ * put_device(). However, this will not happens as fn(dev, data) runs
++ * with its own reference to device via klist_node so it is not its last reference.
++ * so, above situation would not occur.
++ */
++
+ static ssize_t disabled_store(struct class *class, struct class_attribute *attr,
+ const char *buf, size_t count)
+ {
+@@ -278,13 +353,16 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+ devcd->read = read;
+ devcd->free = free;
+ devcd->failing_dev = get_device(dev);
++ devcd->delete_work = false;
+
++ mutex_init(&devcd->mutex);
+ device_initialize(&devcd->devcd_dev);
+
+ dev_set_name(&devcd->devcd_dev, "devcd%d",
+ atomic_inc_return(&devcd_count));
+ devcd->devcd_dev.class = &devcd_class;
+
++ mutex_lock(&devcd->mutex);
+ if (device_add(&devcd->devcd_dev))
+ goto put_device;
+
+@@ -301,10 +379,11 @@ void dev_coredumpm(struct device *dev, struct module *owner,
+
+ INIT_DELAYED_WORK(&devcd->del_wk, devcd_del);
+ schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT);
+-
++ mutex_unlock(&devcd->mutex);
+ return;
+ put_device:
+ put_device(&devcd->devcd_dev);
++ mutex_unlock(&devcd->mutex);
+ put_module:
+ module_put(owner);
+ free:
+--
+2.42.0
+
--- /dev/null
+From 9430fe3d043ff8df420657ea1904a29f60d09bb7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:49:29 -0300
+Subject: smb: client: fix potential NULL deref in parse_dfs_referrals()
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 92414333eb375ed64f4ae92d34d579e826936480 ]
+
+If server returned no data for FSCTL_DFS_GET_REFERRALS, @dfs_rsp will
+remain NULL and then parse_dfs_referrals() will dereference it.
+
+Fix this by returning -EIO when no output data is returned.
+
+Besides, we can't fix it in SMB2_ioctl() as some FSCTLs are allowed to
+return no data as per MS-SMB2 2.2.32.
+
+Fixes: 9d49640a21bf ("CIFS: implement get_dfs_refer for SMB2+")
+Cc: stable@vger.kernel.org
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/smb2ops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index d8ce079ba9091..7c2ecbb17f542 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -2926,6 +2926,8 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
+ usleep_range(512, 2048);
+ } while (++retry_count < 5);
+
++ if (!rc && !dfs_rsp)
++ rc = -EIO;
+ if (rc) {
+ if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP)
+ cifs_tcon_dbg(VFS, "%s: ioctl error: rc=%d\n", __func__, rc);
+--
+2.42.0
+