--- /dev/null
+From d7f1b4bdc7108be1b178e1617b5f45c8918e88d7 Mon Sep 17 00:00:00 2001
+From: Morduan Zang <zhangdandan@uniontech.com>
+Date: Wed, 14 Jan 2026 13:30:33 +0800
+Subject: efi/cper: Fix cper_bits_to_str buffer handling and return value
+
+From: Morduan Zang <zhangdandan@uniontech.com>
+
+commit d7f1b4bdc7108be1b178e1617b5f45c8918e88d7 upstream.
+
+The return value calculation was incorrect: `return len - buf_size;`
+Initially `len = buf_size`, then `len` decreases with each operation.
+This results in a negative return value on success.
+
+Fix by returning `buf_size - len` which correctly calculates the actual
+number of bytes written.
+
+Fixes: a976d790f494 ("efi/cper: Add a new helper function to print bitmasks")
+Signed-off-by: Morduan Zang <zhangdandan@uniontech.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/efi/cper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/firmware/efi/cper.c
++++ b/drivers/firmware/efi/cper.c
+@@ -161,7 +161,7 @@ int cper_bits_to_str(char *buf, int buf_
+ len -= size;
+ str += size;
+ }
+- return len - buf_size;
++ return buf_size - len;
+ }
+ EXPORT_SYMBOL_GPL(cper_bits_to_str);
+
--- /dev/null
+From 99bc9f2eb3f79a2b4296d9bf43153e1d10ca50d3 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Tue, 28 May 2024 13:27:17 +1000
+Subject: NFS: add barriers when testing for NFS_FSDATA_BLOCKED
+
+From: NeilBrown <neilb@suse.de>
+
+commit 99bc9f2eb3f79a2b4296d9bf43153e1d10ca50d3 upstream.
+
+dentry->d_fsdata is set to NFS_FSDATA_BLOCKED while unlinking or
+renaming-over a file to ensure that no open succeeds while the NFS
+operation progressed on the server.
+
+Setting dentry->d_fsdata to NFS_FSDATA_BLOCKED is done under ->d_lock
+after checking the refcount is not elevated. Any attempt to open the
+file (through that name) will go through lookp_open() which will take
+->d_lock while incrementing the refcount, we can be sure that once the
+new value is set, __nfs_lookup_revalidate() *will* see the new value and
+will block.
+
+We don't have any locking guarantee that when we set ->d_fsdata to NULL,
+the wait_var_event() in __nfs_lookup_revalidate() will notice.
+wait/wake primitives do NOT provide barriers to guarantee order. We
+must use smp_load_acquire() in wait_var_event() to ensure we look at an
+up-to-date value, and must use smp_store_release() before wake_up_var().
+
+This patch adds those barrier functions and factors out
+block_revalidate() and unblock_revalidate() far clarity.
+
+There is also a hypothetical bug in that if memory allocation fails
+(which never happens in practice) we might leave ->d_fsdata locked.
+This patch adds the missing call to unblock_revalidate().
+
+Reported-and-tested-by: Richard Kojedzinszky <richard+debian+bugreport@kojedz.in>
+Closes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1071501
+Fixes: 3c59366c207e ("NFS: don't unhash dentry during unlink/rename")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/dir.c | 48 ++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 32 insertions(+), 16 deletions(-)
+
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1421,9 +1421,10 @@ __nfs_lookup_revalidate(struct dentry *d
+ if (parent != READ_ONCE(dentry->d_parent))
+ return -ECHILD;
+ } else {
+- /* Wait for unlink to complete */
++ /* Wait for unlink to complete - see unblock_revalidate() */
+ wait_var_event(&dentry->d_fsdata,
+- dentry->d_fsdata != NFS_FSDATA_BLOCKED);
++ smp_load_acquire(&dentry->d_fsdata)
++ != NFS_FSDATA_BLOCKED);
+ parent = dget_parent(dentry);
+ ret = reval(d_inode(parent), dentry, flags);
+ dput(parent);
+@@ -1436,6 +1437,29 @@ static int nfs_lookup_revalidate(struct
+ return __nfs_lookup_revalidate(dentry, flags, nfs_do_lookup_revalidate);
+ }
+
++static void block_revalidate(struct dentry *dentry)
++{
++ /* old devname - just in case */
++ kfree(dentry->d_fsdata);
++
++ /* Any new reference that could lead to an open
++ * will take ->d_lock in lookup_open() -> d_lookup().
++ * Holding this lock ensures we cannot race with
++ * __nfs_lookup_revalidate() and removes and need
++ * for further barriers.
++ */
++ lockdep_assert_held(&dentry->d_lock);
++
++ dentry->d_fsdata = NFS_FSDATA_BLOCKED;
++}
++
++static void unblock_revalidate(struct dentry *dentry)
++{
++ /* store_release ensures wait_var_event() sees the update */
++ smp_store_release(&dentry->d_fsdata, NULL);
++ wake_up_var(&dentry->d_fsdata);
++}
++
+ /*
+ * A weaker form of d_revalidate for revalidating just the d_inode(dentry)
+ * when we don't really care about the dentry name. This is called when a
+@@ -2114,16 +2138,12 @@ int nfs_unlink(struct inode *dir, struct
+ spin_unlock(&dentry->d_lock);
+ goto out;
+ }
+- if (dentry->d_fsdata)
+- /* old devname */
+- kfree(dentry->d_fsdata);
+- dentry->d_fsdata = NFS_FSDATA_BLOCKED;
++ block_revalidate(dentry);
+
+ spin_unlock(&dentry->d_lock);
+ error = nfs_safe_remove(dentry);
+ nfs_dentry_remove_handle_error(dir, dentry, error);
+- dentry->d_fsdata = NULL;
+- wake_up_var(&dentry->d_fsdata);
++ unblock_revalidate(dentry);
+ out:
+ trace_nfs_unlink_exit(dir, dentry, error);
+ return error;
+@@ -2231,8 +2251,7 @@ nfs_unblock_rename(struct rpc_task *task
+ {
+ struct dentry *new_dentry = data->new_dentry;
+
+- new_dentry->d_fsdata = NULL;
+- wake_up_var(&new_dentry->d_fsdata);
++ unblock_revalidate(new_dentry);
+ }
+
+ /*
+@@ -2295,11 +2314,6 @@ int nfs_rename(struct inode *old_dir, st
+ if (WARN_ON(new_dentry->d_flags & DCACHE_NFSFS_RENAMED) ||
+ WARN_ON(new_dentry->d_fsdata == NFS_FSDATA_BLOCKED))
+ goto out;
+- if (new_dentry->d_fsdata) {
+- /* old devname */
+- kfree(new_dentry->d_fsdata);
+- new_dentry->d_fsdata = NULL;
+- }
+
+ spin_lock(&new_dentry->d_lock);
+ if (d_count(new_dentry) > 2) {
+@@ -2321,7 +2335,7 @@ int nfs_rename(struct inode *old_dir, st
+ new_dentry = dentry;
+ new_inode = NULL;
+ } else {
+- new_dentry->d_fsdata = NFS_FSDATA_BLOCKED;
++ block_revalidate(new_dentry);
+ must_unblock = true;
+ new_gencount = NFS_I(new_inode)->attr_gencount;
+ spin_unlock(&new_dentry->d_lock);
+@@ -2334,6 +2348,8 @@ int nfs_rename(struct inode *old_dir, st
+ task = nfs_async_rename(old_dir, new_dir, old_dentry, new_dentry,
+ must_unblock ? nfs_unblock_rename : NULL);
+ if (IS_ERR(task)) {
++ if (must_unblock)
++ unblock_revalidate(new_dentry);
+ error = PTR_ERR(task);
+ goto out;
+ }
--- /dev/null
+From f16857e62bac60786104c020ad7c86e2163b2c5b Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Fri, 19 Aug 2022 09:55:59 +1000
+Subject: NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT
+
+From: NeilBrown <neilb@suse.de>
+
+commit f16857e62bac60786104c020ad7c86e2163b2c5b upstream.
+
+nfs_unlink() calls d_delete() twice if it receives ENOENT from the
+server - once in nfs_dentry_handle_enoent() from nfs_safe_remove and
+once in nfs_dentry_remove_handle_error().
+
+nfs_rmddir() also calls it twice - the nfs_dentry_handle_enoent() call
+is direct and inside a region locked with ->rmdir_sem
+
+It is safe to call d_delete() twice if the refcount > 1 as the dentry is
+simply unhashed.
+If the refcount is 1, the first call sets d_inode to NULL and the second
+call crashes.
+
+This patch guards the d_delete() call from nfs_dentry_handle_enoent()
+leaving the one under ->remdir_sem in case that is important.
+
+In mainline it would be safe to remove the d_delete() call. However in
+older kernels to which this might be backported, that would change the
+behaviour of nfs_unlink(). nfs_unlink() used to unhash the dentry which
+resulted in nfs_dentry_handle_enoent() not calling d_delete(). So in
+older kernels we need the d_delete() in nfs_dentry_remove_handle_error()
+when called from nfs_unlink() but not when called from nfs_rmdir().
+
+To make the code work correctly for old and new kernels, and from both
+nfs_unlink() and nfs_rmdir(), we protect the d_delete() call with
+simple_positive(). This ensures it is never called in a circumstance
+where it could crash.
+
+Fixes: 3c59366c207e ("NFS: don't unhash dentry during unlink/rename")
+Fixes: 9019fb391de0 ("NFS: Label the dentry with a verifier in nfs_rmdir() and nfs_unlink()")
+Signed-off-by: NeilBrown <neilb@suse.de>
+Tested-by: Olga Kornievskaia <aglo@umich.edu>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nfs/dir.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -2008,7 +2008,8 @@ static void nfs_dentry_remove_handle_err
+ {
+ switch (error) {
+ case -ENOENT:
+- d_delete(dentry);
++ if (d_really_is_positive(dentry))
++ d_delete(dentry);
+ fallthrough;
+ case 0:
+ nfs_set_verifier(dentry, nfs_save_change_attribute(dir));