From: Greg Kroah-Hartman Date: Mon, 22 Mar 2021 09:56:51 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.263~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee02c55965f1e85a823be52da01289a23a03140f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch ext4-fix-potential-error-in-ext4_do_update_inode.patch genirq-disable-interrupts-for-force-threaded-handlers.patch --- diff --git a/queue-4.9/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch b/queue-4.9/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch new file mode 100644 index 00000000000..413c2c80470 --- /dev/null +++ b/queue-4.9/ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch @@ -0,0 +1,73 @@ +From b7ff91fd030dc9d72ed91b1aab36e445a003af4f Mon Sep 17 00:00:00 2001 +From: "zhangyi (F)" +Date: Wed, 3 Mar 2021 21:17:02 +0800 +Subject: ext4: find old entry again if failed to rename whiteout + +From: zhangyi (F) + +commit b7ff91fd030dc9d72ed91b1aab36e445a003af4f upstream. + +If we failed to add new entry on rename whiteout, we cannot reset the +old->de entry directly, because the old->de could have moved from under +us during make indexed dir. So find the old entry again before reset is +needed, otherwise it may corrupt the filesystem as below. + + /dev/sda: Entry '00000001' in ??? (12) has deleted/unused inode 15. CLEARED. + /dev/sda: Unattached inode 75 + /dev/sda: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY. + +Fixes: 6b4b8e6b4ad ("ext4: fix bug for rename with RENAME_WHITEOUT") +Cc: stable@vger.kernel.org +Signed-off-by: zhangyi (F) +Link: https://lore.kernel.org/r/20210303131703.330415-1-yi.zhang@huawei.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 29 +++++++++++++++++++++++++++-- + 1 file changed, 27 insertions(+), 2 deletions(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3425,6 +3425,31 @@ static int ext4_setent(handle_t *handle, + return 0; + } + ++static void ext4_resetent(handle_t *handle, struct ext4_renament *ent, ++ unsigned ino, unsigned file_type) ++{ ++ struct ext4_renament old = *ent; ++ int retval = 0; ++ ++ /* ++ * old->de could have moved from under us during make indexed dir, ++ * so the old->de may no longer valid and need to find it again ++ * before reset old inode info. ++ */ ++ old.bh = ext4_find_entry(old.dir, &old.dentry->d_name, &old.de, NULL); ++ if (IS_ERR(old.bh)) ++ retval = PTR_ERR(old.bh); ++ if (!old.bh) ++ retval = -ENOENT; ++ if (retval) { ++ ext4_std_error(old.dir->i_sb, retval); ++ return; ++ } ++ ++ ext4_setent(handle, &old, ino, file_type); ++ brelse(old.bh); ++} ++ + static int ext4_find_delete_entry(handle_t *handle, struct inode *dir, + const struct qstr *d_name) + { +@@ -3734,8 +3759,8 @@ static int ext4_rename(struct inode *old + end_rename: + if (whiteout) { + if (retval) { +- ext4_setent(handle, &old, +- old.inode->i_ino, old_file_type); ++ ext4_resetent(handle, &old, ++ old.inode->i_ino, old_file_type); + drop_nlink(whiteout); + } + unlock_new_inode(whiteout); diff --git a/queue-4.9/ext4-fix-potential-error-in-ext4_do_update_inode.patch b/queue-4.9/ext4-fix-potential-error-in-ext4_do_update_inode.patch new file mode 100644 index 00000000000..7ac17eb7c15 --- /dev/null +++ b/queue-4.9/ext4-fix-potential-error-in-ext4_do_update_inode.patch @@ -0,0 +1,47 @@ +From 7d8bd3c76da1d94b85e6c9b7007e20e980bfcfe6 Mon Sep 17 00:00:00 2001 +From: Shijie Luo +Date: Fri, 12 Mar 2021 01:50:51 -0500 +Subject: ext4: fix potential error in ext4_do_update_inode + +From: Shijie Luo + +commit 7d8bd3c76da1d94b85e6c9b7007e20e980bfcfe6 upstream. + +If set_large_file = 1 and errors occur in ext4_handle_dirty_metadata(), +the error code will be overridden, go to out_brelse to avoid this +situation. + +Signed-off-by: Shijie Luo +Link: https://lore.kernel.org/r/20210312065051.36314-1-luoshijie1@huawei.com +Cc: stable@kernel.org +Reviewed-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/inode.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4893,7 +4893,7 @@ static int ext4_do_update_inode(handle_t + struct ext4_inode_info *ei = EXT4_I(inode); + struct buffer_head *bh = iloc->bh; + struct super_block *sb = inode->i_sb; +- int err = 0, rc, block; ++ int err = 0, block; + int need_datasync = 0, set_large_file = 0; + uid_t i_uid; + gid_t i_gid; +@@ -5003,9 +5003,9 @@ static int ext4_do_update_inode(handle_t + bh->b_data); + + BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); +- rc = ext4_handle_dirty_metadata(handle, NULL, bh); +- if (!err) +- err = rc; ++ err = ext4_handle_dirty_metadata(handle, NULL, bh); ++ if (err) ++ goto out_brelse; + ext4_clear_inode_state(inode, EXT4_STATE_NEW); + if (set_large_file) { + BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get write access"); diff --git a/queue-4.9/genirq-disable-interrupts-for-force-threaded-handlers.patch b/queue-4.9/genirq-disable-interrupts-for-force-threaded-handlers.patch new file mode 100644 index 00000000000..4dfca627f01 --- /dev/null +++ b/queue-4.9/genirq-disable-interrupts-for-force-threaded-handlers.patch @@ -0,0 +1,70 @@ +From 81e2073c175b887398e5bca6c004efa89983f58d Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Wed, 17 Mar 2021 15:38:52 +0100 +Subject: genirq: Disable interrupts for force threaded handlers + +From: Thomas Gleixner + +commit 81e2073c175b887398e5bca6c004efa89983f58d upstream. + +With interrupt force threading all device interrupt handlers are invoked +from kernel threads. Contrary to hard interrupt context the invocation only +disables bottom halfs, but not interrupts. This was an oversight back then +because any code like this will have an issue: + +thread(irq_A) + irq_handler(A) + spin_lock(&foo->lock); + +interrupt(irq_B) + irq_handler(B) + spin_lock(&foo->lock); + +This has been triggered with networking (NAPI vs. hrtimers) and console +drivers where printk() happens from an interrupt which interrupted the +force threaded handler. + +Now people noticed and started to change the spin_lock() in the handler to +spin_lock_irqsave() which affects performance or add IRQF_NOTHREAD to the +interrupt request which in turn breaks RT. + +Fix the root cause and not the symptom and disable interrupts before +invoking the force threaded handler which preserves the regular semantics +and the usefulness of the interrupt force threading as a general debugging +tool. + +For not RT this is not changing much, except that during the execution of +the threaded handler interrupts are delayed until the handler +returns. Vs. scheduling and softirq processing there is no difference. + +For RT kernels there is no issue. + +Fixes: 8d32a307e4fa ("genirq: Provide forced interrupt threading") +Reported-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Johan Hovold +Acked-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/r/20210317143859.513307808@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + kernel/irq/manage.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -886,11 +886,15 @@ irq_forced_thread_fn(struct irq_desc *de + irqreturn_t ret; + + local_bh_disable(); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_disable(); + ret = action->thread_fn(action->irq, action->dev_id); + if (ret == IRQ_HANDLED) + atomic_inc(&desc->threads_handled); + + irq_finalize_oneshot(desc, action); ++ if (!IS_ENABLED(CONFIG_PREEMPT_RT)) ++ local_irq_enable(); + local_bh_enable(); + return ret; + } diff --git a/queue-4.9/series b/queue-4.9/series index 38623c26dfb..1ea79666102 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -20,3 +20,6 @@ x86-ioapic-ignore-irq2-again.patch kernel-fs-introduce-and-use-set_restart_fn-and-arch_set_restart_data.patch x86-move-ts_compat-back-to-asm-thread_info.h.patch x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch +ext4-find-old-entry-again-if-failed-to-rename-whiteout.patch +ext4-fix-potential-error-in-ext4_do_update_inode.patch +genirq-disable-interrupts-for-force-threaded-handlers.patch