]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Oct 2019 13:25:04 +0000 (06:25 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 16 Oct 2019 13:25:04 +0000 (06:25 -0700)
added patches:
btrfs-allocate-new-inode-in-nofs-context.patch
btrfs-fix-balance-convert-to-single-on-32-bit-host-cpus.patch
btrfs-fix-incorrect-updating-of-log-root-tree.patch
btrfs-fix-memory-leak-due-to-concurrent-append-writes-with-fiemap.patch
btrfs-fix-uninitialized-ret-in-ref-verify.patch
btrfs-relocation-fix-use-after-free-on-dead-relocation-roots.patch
mips-disable-loongson-mmi-instructions-for-kernel-build.patch
mips-elf_hwcap-export-userspace-ases.patch
nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch
rdma-vmw_pvrdma-free-srq-only-once.patch

12 files changed:
queue-5.3/btrfs-allocate-new-inode-in-nofs-context.patch [new file with mode: 0644]
queue-5.3/btrfs-fix-balance-convert-to-single-on-32-bit-host-cpus.patch [new file with mode: 0644]
queue-5.3/btrfs-fix-incorrect-updating-of-log-root-tree.patch [new file with mode: 0644]
queue-5.3/btrfs-fix-memory-leak-due-to-concurrent-append-writes-with-fiemap.patch [new file with mode: 0644]
queue-5.3/btrfs-fix-uninitialized-ret-in-ref-verify.patch [new file with mode: 0644]
queue-5.3/btrfs-relocation-fix-use-after-free-on-dead-relocation-roots.patch [new file with mode: 0644]
queue-5.3/gpiolib-don-t-clear-flag_is_out-when-emulating-open-.patch
queue-5.3/mips-disable-loongson-mmi-instructions-for-kernel-build.patch [new file with mode: 0644]
queue-5.3/mips-elf_hwcap-export-userspace-ases.patch [new file with mode: 0644]
queue-5.3/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch [new file with mode: 0644]
queue-5.3/rdma-vmw_pvrdma-free-srq-only-once.patch [new file with mode: 0644]
queue-5.3/series

diff --git a/queue-5.3/btrfs-allocate-new-inode-in-nofs-context.patch b/queue-5.3/btrfs-allocate-new-inode-in-nofs-context.patch
new file mode 100644 (file)
index 0000000..3c2fd8e
--- /dev/null
@@ -0,0 +1,88 @@
+From 11a19a90870ea5496a8ded69b86f5b476b6d3355 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 9 Sep 2019 10:12:04 -0400
+Subject: btrfs: allocate new inode in NOFS context
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 11a19a90870ea5496a8ded69b86f5b476b6d3355 upstream.
+
+A user reported a lockdep splat
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.2.11-gentoo #2 Not tainted
+ ------------------------------------------------------
+ kswapd0/711 is trying to acquire lock:
+ 000000007777a663 (sb_internal){.+.+}, at: start_transaction+0x3a8/0x500
+
+but task is already holding lock:
+ 000000000ba86300 (fs_reclaim){+.+.}, at: __fs_reclaim_acquire+0x0/0x30
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #1 (fs_reclaim){+.+.}:
+ kmem_cache_alloc+0x1f/0x1c0
+ btrfs_alloc_inode+0x1f/0x260
+ alloc_inode+0x16/0xa0
+ new_inode+0xe/0xb0
+ btrfs_new_inode+0x70/0x610
+ btrfs_symlink+0xd0/0x420
+ vfs_symlink+0x9c/0x100
+ do_symlinkat+0x66/0xe0
+ do_syscall_64+0x55/0x1c0
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+
+-> #0 (sb_internal){.+.+}:
+ __sb_start_write+0xf6/0x150
+ start_transaction+0x3a8/0x500
+ btrfs_commit_inode_delayed_inode+0x59/0x110
+ btrfs_evict_inode+0x19e/0x4c0
+ evict+0xbc/0x1f0
+ inode_lru_isolate+0x113/0x190
+ __list_lru_walk_one.isra.4+0x5c/0x100
+ list_lru_walk_one+0x32/0x50
+ prune_icache_sb+0x36/0x80
+ super_cache_scan+0x14a/0x1d0
+ do_shrink_slab+0x131/0x320
+ shrink_node+0xf7/0x380
+ balance_pgdat+0x2d5/0x640
+ kswapd+0x2ba/0x5e0
+ kthread+0x147/0x160
+ ret_from_fork+0x24/0x30
+
+other info that might help us debug this:
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(fs_reclaim);
+ lock(sb_internal);
+ lock(fs_reclaim);
+ lock(sb_internal);
+---
+ fs/btrfs/inode.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -6276,13 +6276,16 @@ static struct inode *btrfs_new_inode(str
+       u32 sizes[2];
+       int nitems = name ? 2 : 1;
+       unsigned long ptr;
++      unsigned int nofs_flag;
+       int ret;
+       path = btrfs_alloc_path();
+       if (!path)
+               return ERR_PTR(-ENOMEM);
++      nofs_flag = memalloc_nofs_save();
+       inode = new_inode(fs_info->sb);
++      memalloc_nofs_restore(nofs_flag);
+       if (!inode) {
+               btrfs_free_path(path);
+               return ERR_PTR(-ENOMEM);
diff --git a/queue-5.3/btrfs-fix-balance-convert-to-single-on-32-bit-host-cpus.patch b/queue-5.3/btrfs-fix-balance-convert-to-single-on-32-bit-host-cpus.patch
new file mode 100644 (file)
index 0000000..e5c7d9f
--- /dev/null
@@ -0,0 +1,52 @@
+From 7a54789074a54f64addf5b49bf1994f478337a83 Mon Sep 17 00:00:00 2001
+From: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
+Date: Thu, 12 Sep 2019 19:55:01 -0400
+Subject: btrfs: fix balance convert to single on 32-bit host CPUs
+
+From: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
+
+commit 7a54789074a54f64addf5b49bf1994f478337a83 upstream.
+
+Currently, the command:
+
+       btrfs balance start -dconvert=single,soft .
+
+on a Raspberry Pi produces the following kernel message:
+
+       BTRFS error (device mmcblk0p2): balance: invalid convert data profile single
+
+This fails because we use is_power_of_2(unsigned long) to validate
+the new data profile, the constant for 'single' profile uses bit 48,
+and there are only 32 bits in a long on ARM.
+
+Fix by open-coding the check using u64 variables.
+
+Tested by completing the original balance command on several Raspberry
+Pis.
+
+Fixes: 818255feece6 ("btrfs: use common helper instead of open coding a bit test")
+CC: stable@vger.kernel.org # 4.20+
+Signed-off-by: Zygo Blaxell <ce3g8jdj@umail.furryterror.org>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -3854,7 +3854,11 @@ static int alloc_profile_is_valid(u64 fl
+               return !extended; /* "0" is valid for usual profiles */
+       /* true if exactly one bit set */
+-      return is_power_of_2(flags);
++      /*
++       * Don't use is_power_of_2(unsigned long) because it won't work
++       * for the single profile (1ULL << 48) on 32-bit CPUs.
++       */
++      return flags != 0 && (flags & (flags - 1)) == 0;
+ }
+ static inline int balance_need_close(struct btrfs_fs_info *fs_info)
diff --git a/queue-5.3/btrfs-fix-incorrect-updating-of-log-root-tree.patch b/queue-5.3/btrfs-fix-incorrect-updating-of-log-root-tree.patch
new file mode 100644 (file)
index 0000000..f46306a
--- /dev/null
@@ -0,0 +1,132 @@
+From 4203e968947071586a98b5314fd7ffdea3b4f971 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 30 Sep 2019 16:27:25 -0400
+Subject: btrfs: fix incorrect updating of log root tree
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit 4203e968947071586a98b5314fd7ffdea3b4f971 upstream.
+
+We've historically had reports of being unable to mount file systems
+because the tree log root couldn't be read.  Usually this is the "parent
+transid failure", but could be any of the related errors, including
+"fsid mismatch" or "bad tree block", depending on which block got
+allocated.
+
+The modification of the individual log root items are serialized on the
+per-log root root_mutex.  This means that any modification to the
+per-subvol log root_item is completely protected.
+
+However we update the root item in the log root tree outside of the log
+root tree log_mutex.  We do this in order to allow multiple subvolumes
+to be updated in each log transaction.
+
+This is problematic however because when we are writing the log root
+tree out we update the super block with the _current_ log root node
+information.  Since these two operations happen independently of each
+other, you can end up updating the log root tree in between writing out
+the dirty blocks and setting the super block to point at the current
+root.
+
+This means we'll point at the new root node that hasn't been written
+out, instead of the one we should be pointing at.  Thus whatever garbage
+or old block we end up pointing at complains when we mount the file
+system later and try to replay the log.
+
+Fix this by copying the log's root item into a local root item copy.
+Then once we're safely under the log_root_tree->log_mutex we update the
+root item in the log_root_tree.  This way we do not modify the
+log_root_tree while we're committing it, fixing the problem.
+
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Chris Mason <clm@fb.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/tree-log.c |   36 +++++++++++++++++++++++++++---------
+ 1 file changed, 27 insertions(+), 9 deletions(-)
+
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -2932,7 +2932,8 @@ out:
+  * in the tree of log roots
+  */
+ static int update_log_root(struct btrfs_trans_handle *trans,
+-                         struct btrfs_root *log)
++                         struct btrfs_root *log,
++                         struct btrfs_root_item *root_item)
+ {
+       struct btrfs_fs_info *fs_info = log->fs_info;
+       int ret;
+@@ -2940,10 +2941,10 @@ static int update_log_root(struct btrfs_
+       if (log->log_transid == 1) {
+               /* insert root item on the first sync */
+               ret = btrfs_insert_root(trans, fs_info->log_root_tree,
+-                              &log->root_key, &log->root_item);
++                              &log->root_key, root_item);
+       } else {
+               ret = btrfs_update_root(trans, fs_info->log_root_tree,
+-                              &log->root_key, &log->root_item);
++                              &log->root_key, root_item);
+       }
+       return ret;
+ }
+@@ -3041,6 +3042,7 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_root *log = root->log_root;
+       struct btrfs_root *log_root_tree = fs_info->log_root_tree;
++      struct btrfs_root_item new_root_item;
+       int log_transid = 0;
+       struct btrfs_log_ctx root_log_ctx;
+       struct blk_plug plug;
+@@ -3104,18 +3106,26 @@ int btrfs_sync_log(struct btrfs_trans_ha
+               goto out;
+       }
++      /*
++       * We _must_ update under the root->log_mutex in order to make sure we
++       * have a consistent view of the log root we are trying to commit at
++       * this moment.
++       *
++       * We _must_ copy this into a local copy, because we are not holding the
++       * log_root_tree->log_mutex yet.  This is important because when we
++       * commit the log_root_tree we must have a consistent view of the
++       * log_root_tree when we update the super block to point at the
++       * log_root_tree bytenr.  If we update the log_root_tree here we'll race
++       * with the commit and possibly point at the new block which we may not
++       * have written out.
++       */
+       btrfs_set_root_node(&log->root_item, log->node);
++      memcpy(&new_root_item, &log->root_item, sizeof(new_root_item));
+       root->log_transid++;
+       log->log_transid = root->log_transid;
+       root->log_start_pid = 0;
+       /*
+-       * Update or create log root item under the root's log_mutex to prevent
+-       * races with concurrent log syncs that can lead to failure to update
+-       * log root item because it was not created yet.
+-       */
+-      ret = update_log_root(trans, log);
+-      /*
+        * IO has been started, blocks of the log tree have WRITTEN flag set
+        * in their headers. new modifications of the log will be written to
+        * new positions. so it's safe to allow log writers to go in.
+@@ -3135,6 +3145,14 @@ int btrfs_sync_log(struct btrfs_trans_ha
+       mutex_unlock(&log_root_tree->log_mutex);
+       mutex_lock(&log_root_tree->log_mutex);
++
++      /*
++       * Now we are safe to update the log_root_tree because we're under the
++       * log_mutex, and we're a current writer so we're holding the commit
++       * open until we drop the log_mutex.
++       */
++      ret = update_log_root(trans, log, &new_root_item);
++
+       if (atomic_dec_and_test(&log_root_tree->log_writers)) {
+               /* atomic_dec_and_test implies a barrier */
+               cond_wake_up_nomb(&log_root_tree->log_writer_wait);
diff --git a/queue-5.3/btrfs-fix-memory-leak-due-to-concurrent-append-writes-with-fiemap.patch b/queue-5.3/btrfs-fix-memory-leak-due-to-concurrent-append-writes-with-fiemap.patch
new file mode 100644 (file)
index 0000000..ab0f85d
--- /dev/null
@@ -0,0 +1,150 @@
+From c67d970f0ea8dcc423e112137d34334fa0abb8ec Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 30 Sep 2019 10:20:25 +0100
+Subject: Btrfs: fix memory leak due to concurrent append writes with fiemap
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit c67d970f0ea8dcc423e112137d34334fa0abb8ec upstream.
+
+When we have a buffered write that starts at an offset greater than or
+equals to the file's size happening concurrently with a full ranged
+fiemap, we can end up leaking an extent state structure.
+
+Suppose we have a file with a size of 1Mb, and before the buffered write
+and fiemap are performed, it has a single extent state in its io tree
+representing the range from 0 to 1Mb, with the EXTENT_DELALLOC bit set.
+
+The following sequence diagram shows how the memory leak happens if a
+fiemap a buffered write, starting at offset 1Mb and with a length of
+4Kb, are performed concurrently.
+
+          CPU 1                                                  CPU 2
+
+  extent_fiemap()
+    --> it's a full ranged fiemap
+        range from 0 to LLONG_MAX - 1
+        (9223372036854775807)
+
+    --> locks range in the inode's
+        io tree
+      --> after this we have 2 extent
+          states in the io tree:
+          --> 1 for range [0, 1Mb[ with
+              the bits EXTENT_LOCKED and
+              EXTENT_DELALLOC_BITS set
+          --> 1 for the range
+              [1Mb, LLONG_MAX[ with
+              the EXTENT_LOCKED bit set
+
+                                                  --> start buffered write at offset
+                                                      1Mb with a length of 4Kb
+
+                                                  btrfs_file_write_iter()
+
+                                                    btrfs_buffered_write()
+                                                      --> cached_state is NULL
+
+                                                      lock_and_cleanup_extent_if_need()
+                                                        --> returns 0 and does not lock
+                                                            range because it starts
+                                                            at current i_size / eof
+
+                                                      --> cached_state remains NULL
+
+                                                      btrfs_dirty_pages()
+                                                        btrfs_set_extent_delalloc()
+                                                          (...)
+                                                          __set_extent_bit()
+
+                                                            --> splits extent state for range
+                                                                [1Mb, LLONG_MAX[ and now we
+                                                                have 2 extent states:
+
+                                                                --> one for the range
+                                                                    [1Mb, 1Mb + 4Kb[ with
+                                                                    EXTENT_LOCKED set
+                                                                --> another one for the range
+                                                                    [1Mb + 4Kb, LLONG_MAX[ with
+                                                                    EXTENT_LOCKED set as well
+
+                                                            --> sets EXTENT_DELALLOC on the
+                                                                extent state for the range
+                                                                [1Mb, 1Mb + 4Kb[
+                                                            --> caches extent state
+                                                                [1Mb, 1Mb + 4Kb[ into
+                                                                @cached_state because it has
+                                                                the bit EXTENT_LOCKED set
+
+                                                    --> btrfs_buffered_write() ends up
+                                                        with a non-NULL cached_state and
+                                                        never calls anything to release its
+                                                        reference on it, resulting in a
+                                                        memory leak
+
+Fix this by calling free_extent_state() on cached_state if the range was
+not locked by lock_and_cleanup_extent_if_need().
+
+The same issue can happen if anything else other than fiemap locks a range
+that covers eof and beyond.
+
+This could be triggered, sporadically, by test case generic/561 from the
+fstests suite, which makes duperemove run concurrently with fsstress, and
+duperemove does plenty of calls to fiemap. When CONFIG_BTRFS_DEBUG is set
+the leak is reported in dmesg/syslog when removing the btrfs module with
+a message like the following:
+
+  [77100.039461] BTRFS: state leak: start 6574080 end 6582271 state 16402 in tree 0 refs 1
+
+Otherwise (CONFIG_BTRFS_DEBUG not set) detectable with kmemleak.
+
+CC: stable@vger.kernel.org # 4.16+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/file.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1591,7 +1591,6 @@ static noinline ssize_t btrfs_buffered_w
+       struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
+       struct btrfs_root *root = BTRFS_I(inode)->root;
+       struct page **pages = NULL;
+-      struct extent_state *cached_state = NULL;
+       struct extent_changeset *data_reserved = NULL;
+       u64 release_bytes = 0;
+       u64 lockstart;
+@@ -1611,6 +1610,7 @@ static noinline ssize_t btrfs_buffered_w
+               return -ENOMEM;
+       while (iov_iter_count(i) > 0) {
++              struct extent_state *cached_state = NULL;
+               size_t offset = offset_in_page(pos);
+               size_t sector_offset;
+               size_t write_bytes = min(iov_iter_count(i),
+@@ -1758,9 +1758,20 @@ again:
+               if (copied > 0)
+                       ret = btrfs_dirty_pages(inode, pages, dirty_pages,
+                                               pos, copied, &cached_state);
++
++              /*
++               * If we have not locked the extent range, because the range's
++               * start offset is >= i_size, we might still have a non-NULL
++               * cached extent state, acquired while marking the extent range
++               * as delalloc through btrfs_dirty_pages(). Therefore free any
++               * possible cached extent state to avoid a memory leak.
++               */
+               if (extents_locked)
+                       unlock_extent_cached(&BTRFS_I(inode)->io_tree,
+                                            lockstart, lockend, &cached_state);
++              else
++                      free_extent_state(cached_state);
++
+               btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes,
+                                              true);
+               if (ret) {
diff --git a/queue-5.3/btrfs-fix-uninitialized-ret-in-ref-verify.patch b/queue-5.3/btrfs-fix-uninitialized-ret-in-ref-verify.patch
new file mode 100644 (file)
index 0000000..3ce57fd
--- /dev/null
@@ -0,0 +1,37 @@
+From c5f4987e86f6692fdb12533ea1fc7a7bb98e555a Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Wed, 2 Oct 2019 10:03:36 -0400
+Subject: btrfs: fix uninitialized ret in ref-verify
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit c5f4987e86f6692fdb12533ea1fc7a7bb98e555a upstream.
+
+Coverity caught a case where we could return with a uninitialized value
+in ret in process_leaf.  This is actually pretty likely because we could
+very easily run into a block group item key and have a garbage value in
+ret and think there was an errror.  Fix this by initializing ret to 0.
+
+Reported-by: Colin Ian King <colin.king@canonical.com>
+Fixes: fd708b81d972 ("Btrfs: add a extent ref verify tool")
+CC: stable@vger.kernel.org # 4.19+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ref-verify.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/ref-verify.c
++++ b/fs/btrfs/ref-verify.c
+@@ -500,7 +500,7 @@ static int process_leaf(struct btrfs_roo
+       struct btrfs_extent_data_ref *dref;
+       struct btrfs_shared_data_ref *sref;
+       u32 count;
+-      int i = 0, tree_block_level = 0, ret;
++      int i = 0, tree_block_level = 0, ret = 0;
+       struct btrfs_key key;
+       int nritems = btrfs_header_nritems(leaf);
diff --git a/queue-5.3/btrfs-relocation-fix-use-after-free-on-dead-relocation-roots.patch b/queue-5.3/btrfs-relocation-fix-use-after-free-on-dead-relocation-roots.patch
new file mode 100644 (file)
index 0000000..aa59007
--- /dev/null
@@ -0,0 +1,209 @@
+From 1fac4a54374f7ef385938f3c6cf7649c0fe4f6cd Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Mon, 23 Sep 2019 14:56:14 +0800
+Subject: btrfs: relocation: fix use-after-free on dead relocation roots
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit 1fac4a54374f7ef385938f3c6cf7649c0fe4f6cd upstream.
+
+[BUG]
+One user reported a reproducible KASAN report about use-after-free:
+
+  BTRFS info (device sdi1): balance: start -dvrange=1256811659264..1256811659265
+  BTRFS info (device sdi1): relocating block group 1256811659264 flags data|raid0
+  ==================================================================
+  BUG: KASAN: use-after-free in btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
+  Write of size 8 at addr ffff88856f671710 by task kworker/u24:10/261579
+
+  CPU: 2 PID: 261579 Comm: kworker/u24:10 Tainted: P           OE     5.2.11-arch1-1-kasan #4
+  Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./X99 Extreme4, BIOS P3.80 04/06/2018
+  Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs]
+  Call Trace:
+   dump_stack+0x7b/0xba
+   print_address_description+0x6c/0x22e
+   ? btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
+   __kasan_report.cold+0x1b/0x3b
+   ? btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
+   kasan_report+0x12/0x17
+   __asan_report_store8_noabort+0x17/0x20
+   btrfs_init_reloc_root+0x2cd/0x340 [btrfs]
+   record_root_in_trans+0x2a0/0x370 [btrfs]
+   btrfs_record_root_in_trans+0xf4/0x140 [btrfs]
+   start_transaction+0x1ab/0xe90 [btrfs]
+   btrfs_join_transaction+0x1d/0x20 [btrfs]
+   btrfs_finish_ordered_io+0x7bf/0x18a0 [btrfs]
+   ? lock_repin_lock+0x400/0x400
+   ? __kmem_cache_shutdown.cold+0x140/0x1ad
+   ? btrfs_unlink_subvol+0x9b0/0x9b0 [btrfs]
+   finish_ordered_fn+0x15/0x20 [btrfs]
+   normal_work_helper+0x1bd/0xca0 [btrfs]
+   ? process_one_work+0x819/0x1720
+   ? kasan_check_read+0x11/0x20
+   btrfs_endio_write_helper+0x12/0x20 [btrfs]
+   process_one_work+0x8c9/0x1720
+   ? pwq_dec_nr_in_flight+0x2f0/0x2f0
+   ? worker_thread+0x1d9/0x1030
+   worker_thread+0x98/0x1030
+   kthread+0x2bb/0x3b0
+   ? process_one_work+0x1720/0x1720
+   ? kthread_park+0x120/0x120
+   ret_from_fork+0x35/0x40
+
+  Allocated by task 369692:
+   __kasan_kmalloc.part.0+0x44/0xc0
+   __kasan_kmalloc.constprop.0+0xba/0xc0
+   kasan_kmalloc+0x9/0x10
+   kmem_cache_alloc_trace+0x138/0x260
+   btrfs_read_tree_root+0x92/0x360 [btrfs]
+   btrfs_read_fs_root+0x10/0xb0 [btrfs]
+   create_reloc_root+0x47d/0xa10 [btrfs]
+   btrfs_init_reloc_root+0x1e2/0x340 [btrfs]
+   record_root_in_trans+0x2a0/0x370 [btrfs]
+   btrfs_record_root_in_trans+0xf4/0x140 [btrfs]
+   start_transaction+0x1ab/0xe90 [btrfs]
+   btrfs_start_transaction+0x1e/0x20 [btrfs]
+   __btrfs_prealloc_file_range+0x1c2/0xa00 [btrfs]
+   btrfs_prealloc_file_range+0x13/0x20 [btrfs]
+   prealloc_file_extent_cluster+0x29f/0x570 [btrfs]
+   relocate_file_extent_cluster+0x193/0xc30 [btrfs]
+   relocate_data_extent+0x1f8/0x490 [btrfs]
+   relocate_block_group+0x600/0x1060 [btrfs]
+   btrfs_relocate_block_group+0x3a0/0xa00 [btrfs]
+   btrfs_relocate_chunk+0x9e/0x180 [btrfs]
+   btrfs_balance+0x14e4/0x2fc0 [btrfs]
+   btrfs_ioctl_balance+0x47f/0x640 [btrfs]
+   btrfs_ioctl+0x119d/0x8380 [btrfs]
+   do_vfs_ioctl+0x9f5/0x1060
+   ksys_ioctl+0x67/0x90
+   __x64_sys_ioctl+0x73/0xb0
+   do_syscall_64+0xa5/0x370
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  Freed by task 369692:
+   __kasan_slab_free+0x14f/0x210
+   kasan_slab_free+0xe/0x10
+   kfree+0xd8/0x270
+   btrfs_drop_snapshot+0x154c/0x1eb0 [btrfs]
+   clean_dirty_subvols+0x227/0x340 [btrfs]
+   relocate_block_group+0x972/0x1060 [btrfs]
+   btrfs_relocate_block_group+0x3a0/0xa00 [btrfs]
+   btrfs_relocate_chunk+0x9e/0x180 [btrfs]
+   btrfs_balance+0x14e4/0x2fc0 [btrfs]
+   btrfs_ioctl_balance+0x47f/0x640 [btrfs]
+   btrfs_ioctl+0x119d/0x8380 [btrfs]
+   do_vfs_ioctl+0x9f5/0x1060
+   ksys_ioctl+0x67/0x90
+   __x64_sys_ioctl+0x73/0xb0
+   do_syscall_64+0xa5/0x370
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+  The buggy address belongs to the object at ffff88856f671100
+   which belongs to the cache kmalloc-4k of size 4096
+  The buggy address is located 1552 bytes inside of
+   4096-byte region [ffff88856f671100, ffff88856f672100)
+  The buggy address belongs to the page:
+  page:ffffea0015bd9c00 refcount:1 mapcount:0 mapping:ffff88864400e600 index:0x0 compound_mapcount: 0
+  flags: 0x2ffff0000010200(slab|head)
+  raw: 02ffff0000010200 dead000000000100 dead000000000200 ffff88864400e600
+  raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
+  page dumped because: kasan: bad access detected
+
+  Memory state around the buggy address:
+   ffff88856f671600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+   ffff88856f671680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+  >ffff88856f671700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+                           ^
+   ffff88856f671780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+   ffff88856f671800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
+  ==================================================================
+  BTRFS info (device sdi1): 1 enospc errors during balance
+  BTRFS info (device sdi1): balance: ended with status: -28
+
+[CAUSE]
+The problem happens when finish_ordered_io() get called with balance
+still running, while the reloc root of that subvolume is already dead.
+(Tree is swap already done, but tree not yet deleted for possible qgroup
+usage.)
+
+That means root->reloc_root still exists, but that reloc_root can be
+under btrfs_drop_snapshot(), thus we shouldn't access it.
+
+The following race could cause the use-after-free problem:
+
+                CPU1              |                CPU2
+--------------------------------------------------------------------------
+                                  | relocate_block_group()
+                                  | |- unset_reloc_control(rc)
+                                  | |- btrfs_commit_transaction()
+btrfs_finish_ordered_io()         | |- clean_dirty_subvols()
+|- btrfs_join_transaction()       |    |
+   |- record_root_in_trans()      |    |
+      |- btrfs_init_reloc_root()  |    |
+         |- if (root->reloc_root) |    |
+         |                        |    |- root->reloc_root = NULL
+         |                        |    |- btrfs_drop_snapshot(reloc_root);
+         |- reloc_root->last_trans|
+                 = trans->transid |
+           ^^^^^^^^^^^^^^^^^^^^^^
+            Use after free
+
+[FIX]
+Fix it by the following modifications:
+
+- Test if the root has dead reloc tree before accessing root->reloc_root
+  If the root has BTRFS_ROOT_DEAD_RELOC_TREE, then we don't need to
+  create or update root->reloc_tree
+
+- Clear the BTRFS_ROOT_DEAD_RELOC_TREE flag until we have fully dropped
+  reloc tree
+  To co-operate with above modification, so as long as
+  BTRFS_ROOT_DEAD_RELOC_TREE is still set, we won't try to re-create
+  reloc tree at record_root_in_trans().
+
+Reported-by: Cebtenzzre <cebtenzzre@gmail.com>
+Fixes: d2311e698578 ("btrfs: relocation: Delay reloc tree deletion after merge_reloc_roots")
+CC: stable@vger.kernel.org # 5.1+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/relocation.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1434,6 +1434,13 @@ int btrfs_init_reloc_root(struct btrfs_t
+       int clear_rsv = 0;
+       int ret;
++      /*
++       * The subvolume has reloc tree but the swap is finished, no need to
++       * create/update the dead reloc tree
++       */
++      if (test_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state))
++              return 0;
++
+       if (root->reloc_root) {
+               reloc_root = root->reloc_root;
+               reloc_root->last_trans = trans->transid;
+@@ -2186,7 +2193,6 @@ static int clean_dirty_subvols(struct re
+                       /* Merged subvolume, cleanup its reloc root */
+                       struct btrfs_root *reloc_root = root->reloc_root;
+-                      clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
+                       list_del_init(&root->reloc_dirty_list);
+                       root->reloc_root = NULL;
+                       if (reloc_root) {
+@@ -2195,6 +2201,7 @@ static int clean_dirty_subvols(struct re
+                               if (ret2 < 0 && !ret)
+                                       ret = ret2;
+                       }
++                      clear_bit(BTRFS_ROOT_DEAD_RELOC_TREE, &root->state);
+                       btrfs_put_fs_root(root);
+               } else {
+                       /* Orphan reloc tree, just clean it up */
index 60024bd9e00073bbc15a2c66f876e45e6a8d2525..c186b0772ce48c6bd49a2e196930934d1b273ed7 100644 (file)
@@ -25,14 +25,12 @@ Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
 Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- drivers/gpio/gpiolib.c | 27 +++++++++++++++++++--------
+ drivers/gpio/gpiolib.c |   27 +++++++++++++++++++--------
  1 file changed, 19 insertions(+), 8 deletions(-)
 
-diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index e4203c1eb869d..74a77001b1bd7 100644
 --- a/drivers/gpio/gpiolib.c
 +++ b/drivers/gpio/gpiolib.c
-@@ -2775,8 +2775,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
+@@ -2775,8 +2775,10 @@ int gpiod_direction_output(struct gpio_d
                if (!ret)
                        goto set_output_value;
                /* Emulate open drain by not actively driving the line high */
@@ -45,7 +43,7 @@ index e4203c1eb869d..74a77001b1bd7 100644
        }
        else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
                ret = gpio_set_config(gc, gpio_chip_hwgpio(desc),
-@@ -2784,8 +2786,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
+@@ -2784,8 +2786,10 @@ int gpiod_direction_output(struct gpio_d
                if (!ret)
                        goto set_output_value;
                /* Emulate open source by not actively driving the line low */
@@ -58,7 +56,7 @@ index e4203c1eb869d..74a77001b1bd7 100644
        } else {
                gpio_set_config(gc, gpio_chip_hwgpio(desc),
                                PIN_CONFIG_DRIVE_PUSH_PULL);
-@@ -2793,6 +2797,17 @@ int gpiod_direction_output(struct gpio_desc *desc, int value)
+@@ -2793,6 +2797,17 @@ int gpiod_direction_output(struct gpio_d
  
  set_output_value:
        return gpiod_direction_output_raw_commit(desc, value);
@@ -76,7 +74,7 @@ index e4203c1eb869d..74a77001b1bd7 100644
  }
  EXPORT_SYMBOL_GPL(gpiod_direction_output);
  
-@@ -3153,8 +3168,6 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
+@@ -3153,8 +3168,6 @@ static void gpio_set_open_drain_value_co
  
        if (value) {
                err = chip->direction_input(chip, offset);
@@ -85,7 +83,7 @@ index e4203c1eb869d..74a77001b1bd7 100644
        } else {
                err = chip->direction_output(chip, offset, 0);
                if (!err)
-@@ -3184,8 +3197,6 @@ static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value
+@@ -3184,8 +3197,6 @@ static void gpio_set_open_source_value_c
                        set_bit(FLAG_IS_OUT, &desc->flags);
        } else {
                err = chip->direction_input(chip, offset);
@@ -94,6 +92,3 @@ index e4203c1eb869d..74a77001b1bd7 100644
        }
        trace_gpio_direction(desc_to_gpio(desc), !value, err);
        if (err < 0)
--- 
-2.20.1
-
diff --git a/queue-5.3/mips-disable-loongson-mmi-instructions-for-kernel-build.patch b/queue-5.3/mips-disable-loongson-mmi-instructions-for-kernel-build.patch
new file mode 100644 (file)
index 0000000..6748b7e
--- /dev/null
@@ -0,0 +1,60 @@
+From 2f2b4fd674cadd8c6b40eb629e140a14db4068fd Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton@mips.com>
+Date: Thu, 10 Oct 2019 18:54:03 +0000
+Subject: MIPS: Disable Loongson MMI instructions for kernel build
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Paul Burton <paul.burton@mips.com>
+
+commit 2f2b4fd674cadd8c6b40eb629e140a14db4068fd upstream.
+
+GCC 9.x automatically enables support for Loongson MMI instructions when
+using some -march= flags, and then errors out when -msoft-float is
+specified with:
+
+  cc1: error: ‘-mloongson-mmi’ must be used with ‘-mhard-float’
+
+The kernel shouldn't be using these MMI instructions anyway, just as it
+doesn't use floating point instructions. Explicitly disable them in
+order to fix the build with GCC 9.x.
+
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Fixes: 3702bba5eb4f ("MIPS: Loongson: Add GCC 4.4 support for Loongson2E")
+Fixes: 6f7a251a259e ("MIPS: Loongson: Add basic Loongson 2F support")
+Fixes: 5188129b8c9f ("MIPS: Loongson-3: Improve -march option and move it to Platform")
+Cc: Huacai Chen <chenhc@lemote.com>
+Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Cc: stable@vger.kernel.org # v2.6.32+
+Cc: linux-mips@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/loongson64/Platform |    4 ++++
+ arch/mips/vdso/Makefile       |    1 +
+ 2 files changed, 5 insertions(+)
+
+--- a/arch/mips/loongson64/Platform
++++ b/arch/mips/loongson64/Platform
+@@ -66,6 +66,10 @@ else
+       $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+ endif
++# Some -march= flags enable MMI instructions, and GCC complains about that
++# support being enabled alongside -msoft-float. Thus explicitly disable MMI.
++cflags-y += $(call cc-option,-mno-loongson-mmi)
++
+ #
+ # Loongson Machines' Support
+ #
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -9,6 +9,7 @@ ccflags-vdso := \
+       $(filter -mmicromips,$(KBUILD_CFLAGS)) \
+       $(filter -march=%,$(KBUILD_CFLAGS)) \
+       $(filter -m%-float,$(KBUILD_CFLAGS)) \
++      $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \
+       -D__VDSO__
+ ifdef CONFIG_CC_IS_CLANG
diff --git a/queue-5.3/mips-elf_hwcap-export-userspace-ases.patch b/queue-5.3/mips-elf_hwcap-export-userspace-ases.patch
new file mode 100644 (file)
index 0000000..0a2fb8a
--- /dev/null
@@ -0,0 +1,89 @@
+From 38dffe1e4dde1d3174fdce09d67370412843ebb5 Mon Sep 17 00:00:00 2001
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Date: Thu, 10 Oct 2019 23:01:57 +0800
+Subject: MIPS: elf_hwcap: Export userspace ASEs
+
+From: Jiaxun Yang <jiaxun.yang@flygoat.com>
+
+commit 38dffe1e4dde1d3174fdce09d67370412843ebb5 upstream.
+
+A Golang developer reported MIPS hwcap isn't reflecting instructions
+that the processor actually supported so programs can't apply optimized
+code at runtime.
+
+Thus we export the ASEs that can be used in userspace programs.
+
+Reported-by: Meng Zhuo <mengzhuo1203@gmail.com>
+Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
+Cc: linux-mips@vger.kernel.org
+Cc: Paul Burton <paul.burton@mips.com>
+Cc: <stable@vger.kernel.org> # 4.14+
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/include/uapi/asm/hwcap.h |   11 +++++++++++
+ arch/mips/kernel/cpu-probe.c       |   33 +++++++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+)
+
+--- a/arch/mips/include/uapi/asm/hwcap.h
++++ b/arch/mips/include/uapi/asm/hwcap.h
+@@ -6,5 +6,16 @@
+ #define HWCAP_MIPS_R6         (1 << 0)
+ #define HWCAP_MIPS_MSA                (1 << 1)
+ #define HWCAP_MIPS_CRC32      (1 << 2)
++#define HWCAP_MIPS_MIPS16     (1 << 3)
++#define HWCAP_MIPS_MDMX     (1 << 4)
++#define HWCAP_MIPS_MIPS3D   (1 << 5)
++#define HWCAP_MIPS_SMARTMIPS (1 << 6)
++#define HWCAP_MIPS_DSP      (1 << 7)
++#define HWCAP_MIPS_DSP2     (1 << 8)
++#define HWCAP_MIPS_DSP3     (1 << 9)
++#define HWCAP_MIPS_MIPS16E2 (1 << 10)
++#define HWCAP_LOONGSON_MMI  (1 << 11)
++#define HWCAP_LOONGSON_EXT  (1 << 12)
++#define HWCAP_LOONGSON_EXT2 (1 << 13)
+ #endif /* _UAPI_ASM_HWCAP_H */
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -2198,6 +2198,39 @@ void cpu_probe(void)
+               elf_hwcap |= HWCAP_MIPS_MSA;
+       }
++      if (cpu_has_mips16)
++              elf_hwcap |= HWCAP_MIPS_MIPS16;
++
++      if (cpu_has_mdmx)
++              elf_hwcap |= HWCAP_MIPS_MDMX;
++
++      if (cpu_has_mips3d)
++              elf_hwcap |= HWCAP_MIPS_MIPS3D;
++
++      if (cpu_has_smartmips)
++              elf_hwcap |= HWCAP_MIPS_SMARTMIPS;
++
++      if (cpu_has_dsp)
++              elf_hwcap |= HWCAP_MIPS_DSP;
++
++      if (cpu_has_dsp2)
++              elf_hwcap |= HWCAP_MIPS_DSP2;
++
++      if (cpu_has_dsp3)
++              elf_hwcap |= HWCAP_MIPS_DSP3;
++
++      if (cpu_has_mips16e2)
++              elf_hwcap |= HWCAP_MIPS_MIPS16E2;
++
++      if (cpu_has_loongson_mmi)
++              elf_hwcap |= HWCAP_LOONGSON_MMI;
++
++      if (cpu_has_loongson_ext)
++              elf_hwcap |= HWCAP_LOONGSON_EXT;
++
++      if (cpu_has_loongson_ext2)
++              elf_hwcap |= HWCAP_LOONGSON_EXT2;
++
+       if (cpu_has_vz)
+               cpu_probe_vz(c);
diff --git a/queue-5.3/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch b/queue-5.3/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch
new file mode 100644 (file)
index 0000000..129dd71
--- /dev/null
@@ -0,0 +1,155 @@
+From 031d73ed768a40684f3ca21992265ffdb6a270bf Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trondmy@gmail.com>
+Date: Mon, 30 Sep 2019 14:02:56 -0400
+Subject: NFS: Fix O_DIRECT accounting of number of bytes read/written
+
+From: Trond Myklebust <trondmy@gmail.com>
+
+commit 031d73ed768a40684f3ca21992265ffdb6a270bf upstream.
+
+When a series of O_DIRECT reads or writes are truncated, either due to
+eof or due to an error, then we should return the number of contiguous
+bytes that were received/sent starting at the offset specified by the
+application.
+
+Currently, we are failing to correctly check contiguity, and so we're
+failing the generic/465 in xfstests when the race between the read
+and write RPCs causes the file to get extended while the 2 reads are
+outstanding. If the first read RPC call wins the race and returns with
+eof set, we should treat the second read RPC as being truncated.
+
+Reported-by: Su Yanjun <suyj.fnst@cn.fujitsu.com>
+Fixes: 1ccbad9f9f9bd ("nfs: fix DIO good bytes calculation")
+Cc: stable@vger.kernel.org # 4.1+
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/direct.c |   78 ++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 43 insertions(+), 35 deletions(-)
+
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -123,32 +123,49 @@ static inline int put_dreq(struct nfs_di
+ }
+ static void
+-nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr)
++nfs_direct_handle_truncated(struct nfs_direct_req *dreq,
++                          const struct nfs_pgio_header *hdr,
++                          ssize_t dreq_len)
++{
++      struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx];
++
++      if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) ||
++            test_bit(NFS_IOHDR_EOF, &hdr->flags)))
++              return;
++      if (dreq->max_count >= dreq_len) {
++              dreq->max_count = dreq_len;
++              if (dreq->count > dreq_len)
++                      dreq->count = dreq_len;
++
++              if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
++                      dreq->error = hdr->error;
++              else /* Clear outstanding error if this is EOF */
++                      dreq->error = 0;
++      }
++      if (mirror->count > dreq_len)
++              mirror->count = dreq_len;
++}
++
++static void
++nfs_direct_count_bytes(struct nfs_direct_req *dreq,
++                     const struct nfs_pgio_header *hdr)
+ {
+-      int i;
+-      ssize_t count;
++      struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx];
++      loff_t hdr_end = hdr->io_start + hdr->good_bytes;
++      ssize_t dreq_len = 0;
+-      WARN_ON_ONCE(dreq->count >= dreq->max_count);
++      if (hdr_end > dreq->io_start)
++              dreq_len = hdr_end - dreq->io_start;
+-      if (dreq->mirror_count == 1) {
+-              dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes;
+-              dreq->count += hdr->good_bytes;
+-      } else {
+-              /* mirrored writes */
+-              count = dreq->mirrors[hdr->pgio_mirror_idx].count;
+-              if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) {
+-                      count = hdr->io_start + hdr->good_bytes - dreq->io_start;
+-                      dreq->mirrors[hdr->pgio_mirror_idx].count = count;
+-              }
+-              /* update the dreq->count by finding the minimum agreed count from all
+-               * mirrors */
+-              count = dreq->mirrors[0].count;
++      nfs_direct_handle_truncated(dreq, hdr, dreq_len);
+-              for (i = 1; i < dreq->mirror_count; i++)
+-                      count = min(count, dreq->mirrors[i].count);
++      if (dreq_len > dreq->max_count)
++              dreq_len = dreq->max_count;
+-              dreq->count = count;
+-      }
++      if (mirror->count < dreq_len)
++              mirror->count = dreq_len;
++      if (dreq->count < dreq_len)
++              dreq->count = dreq_len;
+ }
+ /*
+@@ -402,20 +419,12 @@ static void nfs_direct_read_completion(s
+       struct nfs_direct_req *dreq = hdr->dreq;
+       spin_lock(&dreq->lock);
+-      if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+-              dreq->error = hdr->error;
+-
+       if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
+               spin_unlock(&dreq->lock);
+               goto out_put;
+       }
+-      if (hdr->good_bytes != 0)
+-              nfs_direct_good_bytes(dreq, hdr);
+-
+-      if (test_bit(NFS_IOHDR_EOF, &hdr->flags))
+-              dreq->error = 0;
+-
++      nfs_direct_count_bytes(dreq, hdr);
+       spin_unlock(&dreq->lock);
+       while (!list_empty(&hdr->pages)) {
+@@ -652,6 +661,9 @@ static void nfs_direct_write_reschedule(
+       nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
+       dreq->count = 0;
++      dreq->max_count = 0;
++      list_for_each_entry(req, &reqs, wb_list)
++              dreq->max_count += req->wb_bytes;
+       dreq->verf.committed = NFS_INVALID_STABLE_HOW;
+       nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo);
+       for (i = 0; i < dreq->mirror_count; i++)
+@@ -791,17 +803,13 @@ static void nfs_direct_write_completion(
+       nfs_init_cinfo_from_dreq(&cinfo, dreq);
+       spin_lock(&dreq->lock);
+-
+-      if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
+-              dreq->error = hdr->error;
+-
+       if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
+               spin_unlock(&dreq->lock);
+               goto out_put;
+       }
++      nfs_direct_count_bytes(dreq, hdr);
+       if (hdr->good_bytes != 0) {
+-              nfs_direct_good_bytes(dreq, hdr);
+               if (nfs_write_need_commit(hdr)) {
+                       if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
+                               request_commit = true;
diff --git a/queue-5.3/rdma-vmw_pvrdma-free-srq-only-once.patch b/queue-5.3/rdma-vmw_pvrdma-free-srq-only-once.patch
new file mode 100644 (file)
index 0000000..2988342
--- /dev/null
@@ -0,0 +1,35 @@
+From 18545e8b6871d21aa3386dc42867138da9948a33 Mon Sep 17 00:00:00 2001
+From: Adit Ranadive <aditr@vmware.com>
+Date: Wed, 18 Sep 2019 23:08:00 +0000
+Subject: RDMA/vmw_pvrdma: Free SRQ only once
+
+From: Adit Ranadive <aditr@vmware.com>
+
+commit 18545e8b6871d21aa3386dc42867138da9948a33 upstream.
+
+An extra kfree cleanup was missed since these are now deallocated by core.
+
+Link: https://lore.kernel.org/r/1568848066-12449-1-git-send-email-aditr@vmware.com
+Cc: <stable@vger.kernel.org>
+Fixes: 68e326dea1db ("RDMA: Handle SRQ allocations by IB/core")
+Signed-off-by: Adit Ranadive <aditr@vmware.com>
+Reviewed-by: Vishnu Dasa <vdasa@vmware.com>
+Reviewed-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
+@@ -230,8 +230,6 @@ static void pvrdma_free_srq(struct pvrdm
+       pvrdma_page_dir_cleanup(dev, &srq->pdir);
+-      kfree(srq);
+-
+       atomic_dec(&dev->num_srqs);
+ }
index 90528e9cb3f96b0e5e52fca4050019b08ad5ddc9..6ecd4050e1233d1071b81ca48fbfd5927cc11f7b 100644 (file)
@@ -81,3 +81,13 @@ ib-core-fix-wrong-iterating-on-ports.patch
 firmware-google-increment-vpd-key_len-properly.patch
 gpio-fix-getting-nonexclusive-gpiods-from-dt.patch
 gpiolib-don-t-clear-flag_is_out-when-emulating-open-.patch
+btrfs-relocation-fix-use-after-free-on-dead-relocation-roots.patch
+btrfs-allocate-new-inode-in-nofs-context.patch
+btrfs-fix-balance-convert-to-single-on-32-bit-host-cpus.patch
+btrfs-fix-memory-leak-due-to-concurrent-append-writes-with-fiemap.patch
+btrfs-fix-incorrect-updating-of-log-root-tree.patch
+btrfs-fix-uninitialized-ret-in-ref-verify.patch
+nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch
+mips-disable-loongson-mmi-instructions-for-kernel-build.patch
+mips-elf_hwcap-export-userspace-ases.patch
+rdma-vmw_pvrdma-free-srq-only-once.patch