From: Sasha Levin Date: Mon, 29 Nov 2021 03:16:54 +0000 (-0500) Subject: Fixes for 5.10 X-Git-Tag: v5.15.6~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=879197b1503078da8fbecb2ec036bed8f6baf903;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- 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 index 00000000000..9f2b1740e2b --- /dev/null +++ b/queue-5.10/ceph-properly-handle-statfs-on-multifs-setups.patch @@ -0,0 +1,67 @@ +From 422aa2ab2f59de5888e7b4311379903f2420a504 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Oct 2021 11:12:58 -0400 +Subject: ceph: properly handle statfs on multifs setups + +From: Jeff Layton + +[ 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 +Signed-off-by: Jeff Layton +Reviewed-by: Xiubo Li +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..2466f98e3b9 --- /dev/null +++ b/queue-5.10/f2fs-set-sbi_need_fsck-flag-when-inconsistent-node-b.patch @@ -0,0 +1,38 @@ +From 994e286c954c2e787d21fc8c4971edd01b4149b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Sep 2021 20:46:36 +0800 +Subject: f2fs: set SBI_NEED_FSCK flag when inconsistent node block found + +From: Weichao Guo + +[ 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 +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..9cb7eb4f8d1 --- /dev/null +++ b/queue-5.10/sched-scs-reset-task-stack-state-in-bringup_cpu.patch @@ -0,0 +1,133 @@ +From a61e3acfadcda1c5cf7d953f99cc8412a9b80713 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Nov 2021 11:40:47 +0000 +Subject: sched/scs: Reset task stack state in bringup_cpu() + +From: Mark Rutland + +[ 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 +Signed-off-by: Mark Rutland +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Valentin Schneider +Tested-by: Qian Cai +Link: https://lore.kernel.org/lkml/20211115113310.35693-1-mark.rutland@arm.com/ +Signed-off-by: Sasha Levin +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 + diff --git a/queue-5.10/series b/queue-5.10/series index f4902b977fe..fc9d529c657 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -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 index 00000000000..1e19d7e7e07 --- /dev/null +++ b/queue-5.10/smb3-do-not-error-on-fsync-when-readonly.patch @@ -0,0 +1,94 @@ +From 4803a26646bd3e293f868c95bebe04b2f122086d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Nov 2021 01:47:48 -0600 +Subject: smb3: do not error on fsync when readonly + +From: Steve French + +[ 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 +Tested-by: Julian Sikorski +Suggested-by: Jeremy Allison +Reviewed-by: Paulo Alcantara (SUSE) +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + 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 +