--- /dev/null
+From 8ecebf4d767e2307a946c8905278d6358eda35c3 Mon Sep 17 00:00:00 2001
+From: Robbie Ko <robbieko@synology.com>
+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 <robbieko@synology.com>
+
+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 <robbieko@synology.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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:
--- /dev/null
+From b40341fad6cc2daa195f8090fd3348f18fff640a Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Tue, 29 Sep 2020 12:40:31 -0400
+Subject: ftrace: Move RCU is watching check after recursion check
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+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 <paulmck@kernel.org>
+Fixes: c68c0fa293417 ("ftrace: Have ftrace_ops_get_func() handle RCU and PER_CPU flags too")
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reported-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }
+
--- /dev/null
+From 29b4f5f188571c112713c35cc87eefb46efee612 Mon Sep 17 00:00:00 2001
+From: Tommi Rantala <tommi.t.rantala@nokia.com>
+Date: Thu, 5 Mar 2020 10:37:12 +0200
+Subject: perf top: Fix stdio interface input handling with glibc 2.28+
+
+From: Tommi Rantala <tommi.t.rantala@nokia.com>
+
+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 <tommi.t.rantala@nokia.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: http://lore.kernel.org/lkml/20200305083714.9381-2-tommi.t.rantala@nokia.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);