]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Oct 2020 14:11:18 +0000 (16:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Oct 2020 14:11:18 +0000 (16:11 +0200)
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

queue-4.14/btrfs-fix-unexpected-failure-of-nocow-buffered-writes-after-snapshotting-when-low-on-space.patch [new file with mode: 0644]
queue-4.14/ftrace-move-rcu-is-watching-check-after-recursion-check.patch [new file with mode: 0644]
queue-4.14/mtd-rawnand-sunxi-fix-the-probe-error-path.patch [new file with mode: 0644]
queue-4.14/perf-top-fix-stdio-interface-input-handling-with-glibc-2.28.patch [new file with mode: 0644]
queue-4.14/series

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 (file)
index 0000000..022d3c2
--- /dev/null
@@ -0,0 +1,219 @@
+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:
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 (file)
index 0000000..cddba41
--- /dev/null
@@ -0,0 +1,57 @@
+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);
+       }
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 (file)
index 0000000..eb04273
--- /dev/null
@@ -0,0 +1,34 @@
+From 3d84515ffd8fb657e10fa5b1215e9f095fa7efca Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Tue, 19 May 2020 15:00:26 +0200
+Subject: mtd: rawnand: sunxi: Fix the probe error path
+
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+
+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 <miquel.raynal@bootlin.com>
+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 <nobuhiro1.iwamatsu@toshiba.co.jp>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..1ca61bf
--- /dev/null
@@ -0,0 +1,53 @@
+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);
index 3c50b3e4075a0f942690829809ea5aa19092ca79..ee7a73bcccf42c85dade1e75e70f9d1d5072c726 100644 (file)
@@ -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