]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Mon, 29 Nov 2021 03:16:54 +0000 (22:16 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 29 Nov 2021 03:16:54 +0000 (22:16 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/ceph-properly-handle-statfs-on-multifs-setups.patch [new file with mode: 0644]
queue-5.10/f2fs-set-sbi_need_fsck-flag-when-inconsistent-node-b.patch [new file with mode: 0644]
queue-5.10/sched-scs-reset-task-stack-state-in-bringup_cpu.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/smb3-do-not-error-on-fsync-when-readonly.patch [new file with mode: 0644]

diff --git a/queue-5.10/ceph-properly-handle-statfs-on-multifs-setups.patch b/queue-5.10/ceph-properly-handle-statfs-on-multifs-setups.patch
new file mode 100644 (file)
index 0000000..9f2b174
--- /dev/null
@@ -0,0 +1,67 @@
+From 422aa2ab2f59de5888e7b4311379903f2420a504 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Oct 2021 11:12:58 -0400
+Subject: ceph: properly handle statfs on multifs setups
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit 8cfc0c7ed34f7929ce7e5d7c6eecf4d01ba89a84 ]
+
+ceph_statfs currently stuffs the cluster fsid into the f_fsid field.
+This was fine when we only had a single filesystem per cluster, but now
+that we have multiples we need to use something that will vary between
+them.
+
+Change ceph_statfs to xor each 32-bit chunk of the fsid (aka cluster id)
+into the lower bits of the statfs->f_fsid. Change the lower bits to hold
+the fscid (filesystem ID within the cluster).
+
+That should give us a value that is guaranteed to be unique between
+filesystems within a cluster, and should minimize the chance of
+collisions between mounts of different clusters.
+
+URL: https://tracker.ceph.com/issues/52812
+Reported-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Xiubo Li <xiubli@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/super.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ceph/super.c b/fs/ceph/super.c
+index f33bfb255db8f..08c8d34c98091 100644
+--- a/fs/ceph/super.c
++++ b/fs/ceph/super.c
+@@ -52,8 +52,7 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
+       struct ceph_fs_client *fsc = ceph_inode_to_client(d_inode(dentry));
+       struct ceph_mon_client *monc = &fsc->client->monc;
+       struct ceph_statfs st;
+-      u64 fsid;
+-      int err;
++      int i, err;
+       u64 data_pool;
+       if (fsc->mdsc->mdsmap->m_num_data_pg_pools == 1) {
+@@ -99,12 +98,14 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
+       buf->f_namelen = NAME_MAX;
+       /* Must convert the fsid, for consistent values across arches */
++      buf->f_fsid.val[0] = 0;
+       mutex_lock(&monc->mutex);
+-      fsid = le64_to_cpu(*(__le64 *)(&monc->monmap->fsid)) ^
+-             le64_to_cpu(*((__le64 *)&monc->monmap->fsid + 1));
++      for (i = 0 ; i < sizeof(monc->monmap->fsid) / sizeof(__le32) ; ++i)
++              buf->f_fsid.val[0] ^= le32_to_cpu(((__le32 *)&monc->monmap->fsid)[i]);
+       mutex_unlock(&monc->mutex);
+-      buf->f_fsid = u64_to_fsid(fsid);
++      /* fold the fs_cluster_id into the upper bits */
++      buf->f_fsid.val[1] = monc->fs_cluster_id;
+       return 0;
+ }
+-- 
+2.33.0
+
diff --git a/queue-5.10/f2fs-set-sbi_need_fsck-flag-when-inconsistent-node-b.patch b/queue-5.10/f2fs-set-sbi_need_fsck-flag-when-inconsistent-node-b.patch
new file mode 100644 (file)
index 0000000..2466f98
--- /dev/null
@@ -0,0 +1,38 @@
+From 994e286c954c2e787d21fc8c4971edd01b4149b9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 18 Sep 2021 20:46:36 +0800
+Subject: f2fs: set SBI_NEED_FSCK flag when inconsistent node block found
+
+From: Weichao Guo <guoweichao@oppo.com>
+
+[ Upstream commit 6663b138ded1a59e630c9e605e42aa7fde490cdc ]
+
+Inconsistent node block will cause a file fail to open or read,
+which could make the user process crashes or stucks. Let's mark
+SBI_NEED_FSCK flag to trigger a fix at next fsck time. After
+unlinking the corrupted file, the user process could regenerate
+a new one and work correctly.
+
+Signed-off-by: Weichao Guo <guoweichao@oppo.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/f2fs/node.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
+index 597a145c08ef5..7e625806bd4a2 100644
+--- a/fs/f2fs/node.c
++++ b/fs/f2fs/node.c
+@@ -1389,6 +1389,7 @@ static struct page *__get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid,
+                         nid, nid_of_node(page), ino_of_node(page),
+                         ofs_of_node(page), cpver_of_node(page),
+                         next_blkaddr_of_node(page));
++              set_sbi_flag(sbi, SBI_NEED_FSCK);
+               err = -EINVAL;
+ out_err:
+               ClearPageUptodate(page);
+-- 
+2.33.0
+
diff --git a/queue-5.10/sched-scs-reset-task-stack-state-in-bringup_cpu.patch b/queue-5.10/sched-scs-reset-task-stack-state-in-bringup_cpu.patch
new file mode 100644 (file)
index 0000000..9cb7eb4
--- /dev/null
@@ -0,0 +1,133 @@
+From a61e3acfadcda1c5cf7d953f99cc8412a9b80713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Nov 2021 11:40:47 +0000
+Subject: sched/scs: Reset task stack state in bringup_cpu()
+
+From: Mark Rutland <mark.rutland@arm.com>
+
+[ Upstream commit dce1ca0525bfdc8a69a9343bc714fbc19a2f04b3 ]
+
+To hot unplug a CPU, the idle task on that CPU calls a few layers of C
+code before finally leaving the kernel. When KASAN is in use, poisoned
+shadow is left around for each of the active stack frames, and when
+shadow call stacks are in use. When shadow call stacks (SCS) are in use
+the task's saved SCS SP is left pointing at an arbitrary point within
+the task's shadow call stack.
+
+When a CPU is offlined than onlined back into the kernel, this stale
+state can adversely affect execution. Stale KASAN shadow can alias new
+stackframes and result in bogus KASAN warnings. A stale SCS SP is
+effectively a memory leak, and prevents a portion of the shadow call
+stack being used. Across a number of hotplug cycles the idle task's
+entire shadow call stack can become unusable.
+
+We previously fixed the KASAN issue in commit:
+
+  e1b77c92981a5222 ("sched/kasan: remove stale KASAN poison after hotplug")
+
+... by removing any stale KASAN stack poison immediately prior to
+onlining a CPU.
+
+Subsequently in commit:
+
+  f1a0a376ca0c4ef1 ("sched/core: Initialize the idle task with preemption disabled")
+
+... the refactoring left the KASAN and SCS cleanup in one-time idle
+thread initialization code rather than something invoked prior to each
+CPU being onlined, breaking both as above.
+
+We fixed SCS (but not KASAN) in commit:
+
+  63acd42c0d4942f7 ("sched/scs: Reset the shadow stack when idle_task_exit")
+
+... but as this runs in the context of the idle task being offlined it's
+potentially fragile.
+
+To fix these consistently and more robustly, reset the SCS SP and KASAN
+shadow of a CPU's idle task immediately before we online that CPU in
+bringup_cpu(). This ensures the idle task always has a consistent state
+when it is running, and removes the need to so so when exiting an idle
+task.
+
+Whenever any thread is created, dup_task_struct() will give the task a
+stack which is free of KASAN shadow, and initialize the task's SCS SP,
+so there's no need to specially initialize either for idle thread within
+init_idle(), as this was only necessary to handle hotplug cycles.
+
+I've tested this on arm64 with:
+
+* gcc 11.1.0, defconfig +KASAN_INLINE, KASAN_STACK
+* clang 12.0.0, defconfig +KASAN_INLINE, KASAN_STACK, SHADOW_CALL_STACK
+
+... offlining and onlining CPUS with:
+
+| while true; do
+|   for C in /sys/devices/system/cpu/cpu*/online; do
+|     echo 0 > $C;
+|     echo 1 > $C;
+|   done
+| done
+
+Fixes: f1a0a376ca0c4ef1 ("sched/core: Initialize the idle task with preemption disabled")
+Reported-by: Qian Cai <quic_qiancai@quicinc.com>
+Signed-off-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Valentin Schneider <valentin.schneider@arm.com>
+Tested-by: Qian Cai <quic_qiancai@quicinc.com>
+Link: https://lore.kernel.org/lkml/20211115113310.35693-1-mark.rutland@arm.com/
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cpu.c        | 7 +++++++
+ kernel/sched/core.c | 4 ----
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 67c22941b5f27..c06ced18f78ad 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -31,6 +31,7 @@
+ #include <linux/smpboot.h>
+ #include <linux/relay.h>
+ #include <linux/slab.h>
++#include <linux/scs.h>
+ #include <linux/percpu-rwsem.h>
+ #include <linux/cpuset.h>
+@@ -551,6 +552,12 @@ static int bringup_cpu(unsigned int cpu)
+       struct task_struct *idle = idle_thread_get(cpu);
+       int ret;
++      /*
++       * Reset stale stack state from the last time this CPU was online.
++       */
++      scs_task_reset(idle);
++      kasan_unpoison_task_stack(idle);
++
+       /*
+        * Some architectures have to walk the irq descriptors to
+        * setup the vector space for the cpu which comes online.
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index e456cce772a3a..304aad997da11 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -6523,9 +6523,6 @@ void __init init_idle(struct task_struct *idle, int cpu)
+       idle->se.exec_start = sched_clock();
+       idle->flags |= PF_IDLE;
+-      scs_task_reset(idle);
+-      kasan_unpoison_task_stack(idle);
+-
+ #ifdef CONFIG_SMP
+       /*
+        * Its possible that init_idle() gets called multiple times on a task,
+@@ -6681,7 +6678,6 @@ void idle_task_exit(void)
+               finish_arch_post_lock_switch();
+       }
+-      scs_task_reset(current);
+       /* finish_cpu(), as ran on the BP, will clean up the active_mm state */
+ }
+-- 
+2.33.0
+
index f4902b977fe3910508a2be8088ef2ac64d6007b0..fc9d529c657b7e6571b1be84b868e04908aa0197 100644 (file)
@@ -99,3 +99,7 @@ net-hns3-fix-vf-rss-failed-problem-after-pf-enable-m.patch
 net-mscc-ocelot-don-t-downgrade-timestamping-rx-filt.patch
 net-mscc-ocelot-correctly-report-the-timestamping-rx.patch
 tcp-correctly-handle-increased-zerocopy-args-struct-.patch
+sched-scs-reset-task-stack-state-in-bringup_cpu.patch
+f2fs-set-sbi_need_fsck-flag-when-inconsistent-node-b.patch
+ceph-properly-handle-statfs-on-multifs-setups.patch
+smb3-do-not-error-on-fsync-when-readonly.patch
diff --git a/queue-5.10/smb3-do-not-error-on-fsync-when-readonly.patch b/queue-5.10/smb3-do-not-error-on-fsync-when-readonly.patch
new file mode 100644 (file)
index 0000000..1e19d7e
--- /dev/null
@@ -0,0 +1,94 @@
+From 4803a26646bd3e293f868c95bebe04b2f122086d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Nov 2021 01:47:48 -0600
+Subject: smb3: do not error on fsync when readonly
+
+From: Steve French <stfrench@microsoft.com>
+
+[ Upstream commit 71e6864eacbef0b2645ca043cdfbac272cb6cea3 ]
+
+Linux allows doing a flush/fsync on a file open for read-only,
+but the protocol does not allow that.  If the file passed in
+on the flush is read-only try to find a writeable handle for
+the same inode, if that is not possible skip sending the
+fsync call to the server to avoid breaking the apps.
+
+Reported-by: Julian Sikorski <belegdol@gmail.com>
+Tested-by: Julian Sikorski <belegdol@gmail.com>
+Suggested-by: Jeremy Allison <jra@samba.org>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/cifs/file.c | 35 +++++++++++++++++++++++++++++------
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 67139f9d583f2..6c06870f90184 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -2618,12 +2618,23 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
+       tcon = tlink_tcon(smbfile->tlink);
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
+               server = tcon->ses->server;
+-              if (server->ops->flush)
+-                      rc = server->ops->flush(xid, tcon, &smbfile->fid);
+-              else
++              if (server->ops->flush == NULL) {
+                       rc = -ENOSYS;
++                      goto strict_fsync_exit;
++              }
++
++              if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
++                      smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
++                      if (smbfile) {
++                              rc = server->ops->flush(xid, tcon, &smbfile->fid);
++                              cifsFileInfo_put(smbfile);
++                      } else
++                              cifs_dbg(FYI, "ignore fsync for file not open for write\n");
++              } else
++                      rc = server->ops->flush(xid, tcon, &smbfile->fid);
+       }
++strict_fsync_exit:
+       free_xid(xid);
+       return rc;
+ }
+@@ -2635,6 +2646,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+       struct cifs_tcon *tcon;
+       struct TCP_Server_Info *server;
+       struct cifsFileInfo *smbfile = file->private_data;
++      struct inode *inode = file_inode(file);
+       struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
+       rc = file_write_and_wait_range(file, start, end);
+@@ -2651,12 +2663,23 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
+       tcon = tlink_tcon(smbfile->tlink);
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
+               server = tcon->ses->server;
+-              if (server->ops->flush)
+-                      rc = server->ops->flush(xid, tcon, &smbfile->fid);
+-              else
++              if (server->ops->flush == NULL) {
+                       rc = -ENOSYS;
++                      goto fsync_exit;
++              }
++
++              if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) {
++                      smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY);
++                      if (smbfile) {
++                              rc = server->ops->flush(xid, tcon, &smbfile->fid);
++                              cifsFileInfo_put(smbfile);
++                      } else
++                              cifs_dbg(FYI, "ignore fsync for file not open for write\n");
++              } else
++                      rc = server->ops->flush(xid, tcon, &smbfile->fid);
+       }
++fsync_exit:
+       free_xid(xid);
+       return rc;
+ }
+-- 
+2.33.0
+