From: Greg Kroah-Hartman Date: Fri, 9 Oct 2020 14:11:18 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.4.239~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c15ddc81e727d4dc9a42fd458f542ab028fbed1e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch ftrace-move-rcu-is-watching-check-after-recursion-check.patch mtd-rawnand-sunxi-fix-the-probe-error-path.patch perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch --- diff --git a/queue-4.14/btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch b/queue-4.14/btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch new file mode 100644 index 00000000000..022d3c2d30b --- /dev/null +++ b/queue-4.14/btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch @@ -0,0 +1,219 @@ +From 8ecebf4d767e2307a946c8905278d6358eda35c3 Mon Sep 17 00:00:00 2001 +From: Robbie Ko +Date: Mon, 6 Aug 2018 10:30:30 +0800 +Subject: Btrfs: fix unexpected failure of nocow buffered writes after snapshotting when low on space + +From: Robbie Ko + +commit 8ecebf4d767e2307a946c8905278d6358eda35c3 upstream. + +Commit e9894fd3e3b3 ("Btrfs: fix snapshot vs nocow writting") forced +nocow writes to fallback to COW, during writeback, when a snapshot is +created. This resulted in writes made before creating the snapshot to +unexpectedly fail with ENOSPC during writeback when success (0) was +returned to user space through the write system call. + +The steps leading to this problem are: + +1. When it's not possible to allocate data space for a write, the + buffered write path checks if a NOCOW write is possible. If it is, + it will not reserve space and success (0) is returned to user space. + +2. Then when a snapshot is created, the root's will_be_snapshotted + atomic is incremented and writeback is triggered for all inode's that + belong to the root being snapshotted. Incrementing that atomic forces + all previous writes to fallback to COW during writeback (running + delalloc). + +3. This results in the writeback for the inodes to fail and therefore + setting the ENOSPC error in their mappings, so that a subsequent + fsync on them will report the error to user space. So it's not a + completely silent data loss (since fsync will report ENOSPC) but it's + a very unexpected and undesirable behaviour, because if a clean + shutdown/unmount of the filesystem happens without previous calls to + fsync, it is expected to have the data present in the files after + mounting the filesystem again. + +So fix this by adding a new atomic named snapshot_force_cow to the +root structure which prevents this behaviour and works the following way: + +1. It is incremented when we start to create a snapshot after triggering + writeback and before waiting for writeback to finish. + +2. This new atomic is now what is used by writeback (running delalloc) + to decide whether we need to fallback to COW or not. Because we + incremented this new atomic after triggering writeback in the + snapshot creation ioctl, we ensure that all buffered writes that + happened before snapshot creation will succeed and not fallback to + COW (which would make them fail with ENOSPC). + +3. The existing atomic, will_be_snapshotted, is kept because it is used + to force new buffered writes, that start after we started + snapshotting, to reserve data space even when NOCOW is possible. + This makes these writes fail early with ENOSPC when there's no + available space to allocate, preventing the unexpected behaviour of + writeback later failing with ENOSPC due to a fallback to COW mode. + +Fixes: e9894fd3e3b3 ("Btrfs: fix snapshot vs nocow writting") +Signed-off-by: Robbie Ko +Reviewed-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Anand Jain +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ctree.h | 1 + + fs/btrfs/disk-io.c | 1 + + fs/btrfs/inode.c | 25 ++++--------------------- + fs/btrfs/ioctl.c | 16 ++++++++++++++++ + 4 files changed, 22 insertions(+), 21 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -1257,6 +1257,7 @@ struct btrfs_root { + int send_in_progress; + struct btrfs_subvolume_writers *subv_writers; + atomic_t will_be_snapshotted; ++ atomic_t snapshot_force_cow; + + /* For qgroup metadata space reserve */ + atomic64_t qgroup_meta_rsv; +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1200,6 +1200,7 @@ static void __setup_root(struct btrfs_ro + refcount_set(&root->refs, 1); + atomic_set(&root->will_be_snapshotted, 0); + atomic64_set(&root->qgroup_meta_rsv, 0); ++ atomic_set(&root->snapshot_force_cow, 0); + root->log_transid = 0; + root->log_transid_committed = -1; + root->last_log_commit = 0; +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -1335,7 +1335,7 @@ static noinline int run_delalloc_nocow(s + u64 disk_num_bytes; + u64 ram_bytes; + int extent_type; +- int ret, err; ++ int ret; + int type; + int nocow; + int check_prev = 1; +@@ -1460,11 +1460,8 @@ next_slot: + * if there are pending snapshots for this root, + * we fall into common COW way. + */ +- if (!nolock) { +- err = btrfs_start_write_no_snapshotting(root); +- if (!err) +- goto out_check; +- } ++ if (!nolock && atomic_read(&root->snapshot_force_cow)) ++ goto out_check; + /* + * force cow if csum exists in the range. + * this ensure that csum for a given extent are +@@ -1473,9 +1470,6 @@ next_slot: + ret = csum_exist_in_range(fs_info, disk_bytenr, + num_bytes); + if (ret) { +- if (!nolock) +- btrfs_end_write_no_snapshotting(root); +- + /* + * ret could be -EIO if the above fails to read + * metadata. +@@ -1488,11 +1482,8 @@ next_slot: + WARN_ON_ONCE(nolock); + goto out_check; + } +- if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) { +- if (!nolock) +- btrfs_end_write_no_snapshotting(root); ++ if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) + goto out_check; +- } + nocow = 1; + } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + extent_end = found_key.offset + +@@ -1505,8 +1496,6 @@ next_slot: + out_check: + if (extent_end <= start) { + path->slots[0]++; +- if (!nolock && nocow) +- btrfs_end_write_no_snapshotting(root); + if (nocow) + btrfs_dec_nocow_writers(fs_info, disk_bytenr); + goto next_slot; +@@ -1528,8 +1517,6 @@ out_check: + end, page_started, nr_written, 1, + NULL); + if (ret) { +- if (!nolock && nocow) +- btrfs_end_write_no_snapshotting(root); + if (nocow) + btrfs_dec_nocow_writers(fs_info, + disk_bytenr); +@@ -1549,8 +1536,6 @@ out_check: + ram_bytes, BTRFS_COMPRESS_NONE, + BTRFS_ORDERED_PREALLOC); + if (IS_ERR(em)) { +- if (!nolock && nocow) +- btrfs_end_write_no_snapshotting(root); + if (nocow) + btrfs_dec_nocow_writers(fs_info, + disk_bytenr); +@@ -1589,8 +1574,6 @@ out_check: + EXTENT_CLEAR_DATA_RESV, + PAGE_UNLOCK | PAGE_SET_PRIVATE2); + +- if (!nolock && nocow) +- btrfs_end_write_no_snapshotting(root); + cur_offset = extent_end; + + /* +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -655,6 +655,7 @@ static int create_snapshot(struct btrfs_ + struct btrfs_pending_snapshot *pending_snapshot; + struct btrfs_trans_handle *trans; + int ret; ++ bool snapshot_force_cow = false; + + if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state)) + return -EINVAL; +@@ -671,6 +672,11 @@ static int create_snapshot(struct btrfs_ + goto free_pending; + } + ++ /* ++ * Force new buffered writes to reserve space even when NOCOW is ++ * possible. This is to avoid later writeback (running dealloc) to ++ * fallback to COW mode and unexpectedly fail with ENOSPC. ++ */ + atomic_inc(&root->will_be_snapshotted); + smp_mb__after_atomic(); + btrfs_wait_for_no_snapshotting_writes(root); +@@ -679,6 +685,14 @@ static int create_snapshot(struct btrfs_ + if (ret) + goto dec_and_free; + ++ /* ++ * All previous writes have started writeback in NOCOW mode, so now ++ * we force future writes to fallback to COW mode during snapshot ++ * creation. ++ */ ++ atomic_inc(&root->snapshot_force_cow); ++ snapshot_force_cow = true; ++ + btrfs_wait_ordered_extents(root, U64_MAX, 0, (u64)-1); + + btrfs_init_block_rsv(&pending_snapshot->block_rsv, +@@ -744,6 +758,8 @@ static int create_snapshot(struct btrfs_ + fail: + btrfs_subvolume_release_metadata(fs_info, &pending_snapshot->block_rsv); + dec_and_free: ++ if (snapshot_force_cow) ++ atomic_dec(&root->snapshot_force_cow); + if (atomic_dec_and_test(&root->will_be_snapshotted)) + wake_up_atomic_t(&root->will_be_snapshotted); + free_pending: diff --git a/queue-4.14/ftrace-move-rcu-is-watching-check-after-recursion-check.patch b/queue-4.14/ftrace-move-rcu-is-watching-check-after-recursion-check.patch new file mode 100644 index 00000000000..cddba41149f --- /dev/null +++ b/queue-4.14/ftrace-move-rcu-is-watching-check-after-recursion-check.patch @@ -0,0 +1,57 @@ +From b40341fad6cc2daa195f8090fd3348f18fff640a Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 29 Sep 2020 12:40:31 -0400 +Subject: ftrace: Move RCU is watching check after recursion check + +From: Steven Rostedt (VMware) + +commit b40341fad6cc2daa195f8090fd3348f18fff640a upstream. + +The first thing that the ftrace function callback helper functions should do +is to check for recursion. Peter Zijlstra found that when +"rcu_is_watching()" had its notrace removed, it caused perf function tracing +to crash. This is because the call of rcu_is_watching() is tested before +function recursion is checked and and if it is traced, it will cause an +infinite recursion loop. + +rcu_is_watching() should still stay notrace, but to prevent this should +never had crashed in the first place. The recursion prevention must be the +first thing done in callback functions. + +Link: https://lore.kernel.org/r/20200929112541.GM2628@hirez.programming.kicks-ass.net + +Cc: stable@vger.kernel.org +Cc: Paul McKenney +Fixes: c68c0fa293417 ("ftrace: Have ftrace_ops_get_func() handle RCU and PER_CPU flags too") +Acked-by: Peter Zijlstra (Intel) +Reported-by: Peter Zijlstra (Intel) +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -6159,17 +6159,15 @@ static void ftrace_ops_assist_func(unsig + { + int bit; + +- if ((op->flags & FTRACE_OPS_FL_RCU) && !rcu_is_watching()) +- return; +- + bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX); + if (bit < 0) + return; + + preempt_disable_notrace(); + +- if (!(op->flags & FTRACE_OPS_FL_PER_CPU) || +- !ftrace_function_local_disabled(op)) { ++ if ((!(op->flags & FTRACE_OPS_FL_RCU) || rcu_is_watching()) && ++ (!(op->flags & FTRACE_OPS_FL_PER_CPU) || ++ !ftrace_function_local_disabled(op))) { + op->func(ip, parent_ip, op, regs); + } + diff --git a/queue-4.14/mtd-rawnand-sunxi-fix-the-probe-error-path.patch b/queue-4.14/mtd-rawnand-sunxi-fix-the-probe-error-path.patch new file mode 100644 index 00000000000..eb042730fc5 --- /dev/null +++ b/queue-4.14/mtd-rawnand-sunxi-fix-the-probe-error-path.patch @@ -0,0 +1,34 @@ +From 3d84515ffd8fb657e10fa5b1215e9f095fa7efca Mon Sep 17 00:00:00 2001 +From: Miquel Raynal +Date: Tue, 19 May 2020 15:00:26 +0200 +Subject: mtd: rawnand: sunxi: Fix the probe error path + +From: Miquel Raynal + +commit 3d84515ffd8fb657e10fa5b1215e9f095fa7efca upstream. + +nand_release() is supposed be called after MTD device registration. +Here, only nand_scan() happened, so use nand_cleanup() instead. + +Fixes: 1fef62c1423b ("mtd: nand: add sunxi NAND flash controller support") +Signed-off-by: Miquel Raynal +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/linux-mtd/20200519130035.1883-54-miquel.raynal@bootlin.com +[iwamatsu: adjust filename] +Signed-off-by: Nobuhiro Iwamatsu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mtd/nand/sunxi_nand.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/nand/sunxi_nand.c ++++ b/drivers/mtd/nand/sunxi_nand.c +@@ -2125,7 +2125,7 @@ static int sunxi_nand_chip_init(struct d + ret = mtd_device_register(mtd, NULL, 0); + if (ret) { + dev_err(dev, "failed to register mtd device: %d\n", ret); +- nand_release(nand); ++ nand_cleanup(nand); + return ret; + } + diff --git a/queue-4.14/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch b/queue-4.14/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch new file mode 100644 index 00000000000..1ca61bf3005 --- /dev/null +++ b/queue-4.14/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch @@ -0,0 +1,53 @@ +From 29b4f5f188571c112713c35cc87eefb46efee612 Mon Sep 17 00:00:00 2001 +From: Tommi Rantala +Date: Thu, 5 Mar 2020 10:37:12 +0200 +Subject: perf top: Fix stdio interface input handling with glibc 2.28+ + +From: Tommi Rantala + +commit 29b4f5f188571c112713c35cc87eefb46efee612 upstream. + +Since glibc 2.28 when running 'perf top --stdio', input handling no +longer works, but hitting any key always just prints the "Mapped keys" +help text. + +To fix it, call clearerr() in the display_thread() loop to clear any EOF +sticky errors, as instructed in the glibc NEWS file +(https://sourceware.org/git/?p=glibc.git;a=blob;f=NEWS): + + * All stdio functions now treat end-of-file as a sticky condition. If you + read from a file until EOF, and then the file is enlarged by another + process, you must call clearerr or another function with the same effect + (e.g. fseek, rewind) before you can read the additional data. This + corrects a longstanding C99 conformance bug. It is most likely to affect + programs that use stdio to read interactive input from a terminal. + (Bug #1190.) + +Signed-off-by: Tommi Rantala +Tested-by: Arnaldo Carvalho de Melo +Cc: Alexander Shishkin +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: http://lore.kernel.org/lkml/20200305083714.9381-2-tommi.t.rantala@nokia.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/builtin-top.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/tools/perf/builtin-top.c ++++ b/tools/perf/builtin-top.c +@@ -652,7 +652,9 @@ repeat: + delay_msecs = top->delay_secs * MSEC_PER_SEC; + set_term_quiet_input(&save); + /* trash return*/ +- getc(stdin); ++ clearerr(stdin); ++ if (poll(&stdin_poll, 1, 0) > 0) ++ getc(stdin); + + while (!done) { + perf_top__print_sym_table(top); diff --git a/queue-4.14/series b/queue-4.14/series index 3c50b3e4075..ee7a73bcccf 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -38,3 +38,7 @@ usermodehelper-reset-umask-to-default-before-executing-user-process.patch platform-x86-thinkpad_acpi-initialize-tp_nvram_state-variable.patch platform-x86-thinkpad_acpi-re-initialize-acpi-buffer-size-when-reuse.patch driver-core-fix-probe_count-imbalance-in-really_probe.patch +perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch +mtd-rawnand-sunxi-fix-the-probe-error-path.patch +btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch +ftrace-move-rcu-is-watching-check-after-recursion-check.patch