]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sun, 23 Aug 2020 01:16:35 +0000 (21:16 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 23 Aug 2020 01:16:35 +0000 (21:16 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
12 files changed:
queue-5.4/bcache-avoid-nr_stripes-overflow-in-bcache_device_in.patch [new file with mode: 0644]
queue-5.4/btrfs-add-wrapper-for-transaction-abort-predicate.patch [new file with mode: 0644]
queue-5.4/btrfs-don-t-show-full-path-of-bind-mounts-in-subvol.patch [new file with mode: 0644]
queue-5.4/btrfs-export-helpers-for-subvolume-name-id-resolutio.patch [new file with mode: 0644]
queue-5.4/btrfs-return-erofs-for-btrfs_fs_state_error-cases.patch [new file with mode: 0644]
queue-5.4/drm-vgem-replace-opencoded-version-of-drm_gem_dumb_m.patch [new file with mode: 0644]
queue-5.4/gfs2-improve-mmap-write-vs.-punch_hole-consistency.patch [new file with mode: 0644]
queue-5.4/gfs2-never-call-gfs2_block_zero_range-with-an-open-t.patch [new file with mode: 0644]
queue-5.4/khugepaged-adjust-vm_bug_on_mm-in-__khugepaged_enter.patch [new file with mode: 0644]
queue-5.4/khugepaged-khugepaged_test_exit-check-mmget_still_va.patch [new file with mode: 0644]
queue-5.4/perf-probe-fix-memory-leakage-when-the-probe-point-i.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/bcache-avoid-nr_stripes-overflow-in-bcache_device_in.patch b/queue-5.4/bcache-avoid-nr_stripes-overflow-in-bcache_device_in.patch
new file mode 100644 (file)
index 0000000..36f5dbb
--- /dev/null
@@ -0,0 +1,62 @@
+From ab86df06e46c37649929e12630ce1bb0354e789f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Jul 2020 20:00:21 +0800
+Subject: bcache: avoid nr_stripes overflow in bcache_device_init()
+
+From: Coly Li <colyli@suse.de>
+
+[ Upstream commit 65f0f017e7be8c70330372df23bcb2a407ecf02d ]
+
+For some block devices which large capacity (e.g. 8TB) but small io_opt
+size (e.g. 8 sectors), in bcache_device_init() the stripes number calcu-
+lated by,
+       DIV_ROUND_UP_ULL(sectors, d->stripe_size);
+might be overflow to the unsigned int bcache_device->nr_stripes.
+
+This patch uses the uint64_t variable to store DIV_ROUND_UP_ULL()
+and after the value is checked to be available in unsigned int range,
+sets it to bache_device->nr_stripes. Then the overflow is avoided.
+
+Reported-and-tested-by: Ken Raeburn <raeburn@redhat.com>
+Signed-off-by: Coly Li <colyli@suse.de>
+Cc: stable@vger.kernel.org
+Link: https://bugzilla.redhat.com/show_bug.cgi?id=1783075
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/bcache/super.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
+index 25ad64a3919f6..2cbfcd99b7ee7 100644
+--- a/drivers/md/bcache/super.c
++++ b/drivers/md/bcache/super.c
+@@ -816,19 +816,19 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
+       struct request_queue *q;
+       const size_t max_stripes = min_t(size_t, INT_MAX,
+                                        SIZE_MAX / sizeof(atomic_t));
+-      size_t n;
++      uint64_t n;
+       int idx;
+       if (!d->stripe_size)
+               d->stripe_size = 1 << 31;
+-      d->nr_stripes = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
+-
+-      if (!d->nr_stripes || d->nr_stripes > max_stripes) {
+-              pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)",
+-                      (unsigned int)d->nr_stripes);
++      n = DIV_ROUND_UP_ULL(sectors, d->stripe_size);
++      if (!n || n > max_stripes) {
++              pr_err("nr_stripes too large or invalid: %llu (start sector beyond end of disk?)\n",
++                      n);
+               return -ENOMEM;
+       }
++      d->nr_stripes = n;
+       n = d->nr_stripes * sizeof(atomic_t);
+       d->stripe_sectors_dirty = kvzalloc(n, GFP_KERNEL);
+-- 
+2.25.1
+
diff --git a/queue-5.4/btrfs-add-wrapper-for-transaction-abort-predicate.patch b/queue-5.4/btrfs-add-wrapper-for-transaction-abort-predicate.patch
new file mode 100644 (file)
index 0000000..8644aae
--- /dev/null
@@ -0,0 +1,252 @@
+From f044d112a36247e0dd7eee2c5feb5e0cb6980f9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2020 17:34:34 +0100
+Subject: btrfs: add wrapper for transaction abort predicate
+
+From: David Sterba <dsterba@suse.com>
+
+[ Upstream commit bf31f87f71cc7a89871ab0a451c047a0c0144bf1 ]
+
+The status of aborted transaction can change between calls and it needs
+to be accessed by READ_ONCE. Add a helper that also wraps the unlikely
+hint.
+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/block-group.c   |  2 +-
+ fs/btrfs/delayed-inode.c |  2 +-
+ fs/btrfs/extent-tree.c   | 10 +++++-----
+ fs/btrfs/super.c         |  2 +-
+ fs/btrfs/transaction.c   | 25 +++++++++++++------------
+ fs/btrfs/transaction.h   | 12 ++++++++++++
+ 6 files changed, 33 insertions(+), 20 deletions(-)
+
+diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
+index 42d69e77f89d9..b167649f5f5de 100644
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2168,7 +2168,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
+               return 0;
+       }
+-      if (trans->aborted)
++      if (TRANS_ABORTED(trans))
+               return 0;
+ again:
+       inode = lookup_free_space_inode(block_group, path);
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 5bcccfbcc7c15..a34ee9c2f3151 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1151,7 +1151,7 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr)
+       int ret = 0;
+       bool count = (nr > 0);
+-      if (trans->aborted)
++      if (TRANS_ABORTED(trans))
+               return -EIO;
+       path = btrfs_alloc_path();
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 739332b462059..a36bd4507bacd 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -1561,7 +1561,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
+       int err = 0;
+       int metadata = !extent_op->is_data;
+-      if (trans->aborted)
++      if (TRANS_ABORTED(trans))
+               return 0;
+       if (metadata && !btrfs_fs_incompat(fs_info, SKINNY_METADATA))
+@@ -1681,7 +1681,7 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
+ {
+       int ret = 0;
+-      if (trans->aborted) {
++      if (TRANS_ABORTED(trans)) {
+               if (insert_reserved)
+                       btrfs_pin_extent(trans->fs_info, node->bytenr,
+                                        node->num_bytes, 1);
+@@ -2169,7 +2169,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
+       int run_all = count == (unsigned long)-1;
+       /* We'll clean this up in btrfs_cleanup_transaction */
+-      if (trans->aborted)
++      if (TRANS_ABORTED(trans))
+               return 0;
+       if (test_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags))
+@@ -2892,7 +2892,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
+       else
+               unpin = &fs_info->freed_extents[0];
+-      while (!trans->aborted) {
++      while (!TRANS_ABORTED(trans)) {
+               struct extent_state *cached_state = NULL;
+               mutex_lock(&fs_info->unused_bg_unpin_mutex);
+@@ -2924,7 +2924,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
+               u64 trimmed = 0;
+               ret = -EROFS;
+-              if (!trans->aborted)
++              if (!TRANS_ABORTED(trans))
+                       ret = btrfs_discard_extent(fs_info,
+                                                  block_group->key.objectid,
+                                                  block_group->key.offset,
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index e21cae80c6d58..a1498df419b4f 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -241,7 +241,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
+ {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
+-      trans->aborted = errno;
++      WRITE_ONCE(trans->aborted, errno);
+       /* Nothing used. The other threads that have joined this
+        * transaction may be able to continue. */
+       if (!trans->dirty && list_empty(&trans->new_bgs)) {
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 465ddb297c381..c346ee7ec18d4 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -174,7 +174,7 @@ loop:
+       cur_trans = fs_info->running_transaction;
+       if (cur_trans) {
+-              if (cur_trans->aborted) {
++              if (TRANS_ABORTED(cur_trans)) {
+                       spin_unlock(&fs_info->trans_lock);
+                       return cur_trans->aborted;
+               }
+@@ -390,7 +390,7 @@ static inline int is_transaction_blocked(struct btrfs_transaction *trans)
+ {
+       return (trans->state >= TRANS_STATE_BLOCKED &&
+               trans->state < TRANS_STATE_UNBLOCKED &&
+-              !trans->aborted);
++              !TRANS_ABORTED(trans));
+ }
+ /* wait for commit against the current transaction to become unblocked
+@@ -409,7 +409,7 @@ static void wait_current_trans(struct btrfs_fs_info *fs_info)
+               wait_event(fs_info->transaction_wait,
+                          cur_trans->state >= TRANS_STATE_UNBLOCKED ||
+-                         cur_trans->aborted);
++                         TRANS_ABORTED(cur_trans));
+               btrfs_put_transaction(cur_trans);
+       } else {
+               spin_unlock(&fs_info->trans_lock);
+@@ -870,7 +870,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
+       if (throttle)
+               btrfs_run_delayed_iputs(info);
+-      if (trans->aborted ||
++      if (TRANS_ABORTED(trans) ||
+           test_bit(BTRFS_FS_STATE_ERROR, &info->fs_state)) {
+               wake_up_process(info->transaction_kthread);
+               if (TRANS_ABORTED(trans))
+@@ -1730,7 +1730,8 @@ static void wait_current_trans_commit_start(struct btrfs_fs_info *fs_info,
+                                           struct btrfs_transaction *trans)
+ {
+       wait_event(fs_info->transaction_blocked_wait,
+-                 trans->state >= TRANS_STATE_COMMIT_START || trans->aborted);
++                 trans->state >= TRANS_STATE_COMMIT_START ||
++                 TRANS_ABORTED(trans));
+ }
+ /*
+@@ -1742,7 +1743,8 @@ static void wait_current_trans_commit_start_and_unblock(
+                                       struct btrfs_transaction *trans)
+ {
+       wait_event(fs_info->transaction_wait,
+-                 trans->state >= TRANS_STATE_UNBLOCKED || trans->aborted);
++                 trans->state >= TRANS_STATE_UNBLOCKED ||
++                 TRANS_ABORTED(trans));
+ }
+ /*
+@@ -1960,7 +1962,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+       trans->dirty = true;
+       /* Stop the commit early if ->aborted is set */
+-      if (unlikely(READ_ONCE(cur_trans->aborted))) {
++      if (TRANS_ABORTED(cur_trans)) {
+               ret = cur_trans->aborted;
+               btrfs_end_transaction(trans);
+               return ret;
+@@ -2034,7 +2036,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+               wait_for_commit(cur_trans);
+-              if (unlikely(cur_trans->aborted))
++              if (TRANS_ABORTED(cur_trans))
+                       ret = cur_trans->aborted;
+               btrfs_put_transaction(cur_trans);
+@@ -2053,7 +2055,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+                       spin_unlock(&fs_info->trans_lock);
+                       wait_for_commit(prev_trans);
+-                      ret = prev_trans->aborted;
++                      ret = READ_ONCE(prev_trans->aborted);
+                       btrfs_put_transaction(prev_trans);
+                       if (ret)
+@@ -2107,8 +2109,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+       wait_event(cur_trans->writer_wait,
+                  atomic_read(&cur_trans->num_writers) == 1);
+-      /* ->aborted might be set after the previous check, so check it */
+-      if (unlikely(READ_ONCE(cur_trans->aborted))) {
++      if (TRANS_ABORTED(cur_trans)) {
+               ret = cur_trans->aborted;
+               goto scrub_continue;
+       }
+@@ -2226,7 +2227,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
+        * The tasks which save the space cache and inode cache may also
+        * update ->aborted, check it.
+        */
+-      if (unlikely(READ_ONCE(cur_trans->aborted))) {
++      if (TRANS_ABORTED(cur_trans)) {
+               ret = cur_trans->aborted;
+               mutex_unlock(&fs_info->tree_log_mutex);
+               mutex_unlock(&fs_info->reloc_mutex);
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index b15c31d231488..7291a2a930751 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -116,6 +116,10 @@ struct btrfs_trans_handle {
+       struct btrfs_block_rsv *orig_rsv;
+       refcount_t use_count;
+       unsigned int type;
++      /*
++       * Error code of transaction abort, set outside of locks and must use
++       * the READ_ONCE/WRITE_ONCE access
++       */
+       short aborted;
+       bool adding_csums;
+       bool allocating_chunk;
+@@ -127,6 +131,14 @@ struct btrfs_trans_handle {
+       struct list_head new_bgs;
+ };
++/*
++ * The abort status can be changed between calls and is not protected by locks.
++ * This accepts btrfs_transaction and btrfs_trans_handle as types. Once it's
++ * set to a non-zero value it does not change, so the macro should be in checks
++ * but is not necessary for further reads of the value.
++ */
++#define TRANS_ABORTED(trans)          (unlikely(READ_ONCE((trans)->aborted)))
++
+ struct btrfs_pending_snapshot {
+       struct dentry *dentry;
+       struct inode *dir;
+-- 
+2.25.1
+
diff --git a/queue-5.4/btrfs-don-t-show-full-path-of-bind-mounts-in-subvol.patch b/queue-5.4/btrfs-don-t-show-full-path-of-bind-mounts-in-subvol.patch
new file mode 100644 (file)
index 0000000..a1bcb1f
--- /dev/null
@@ -0,0 +1,67 @@
+From e52292f89964b8c709f8441efd880ad404b09094 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2020 11:12:46 -0400
+Subject: btrfs: don't show full path of bind mounts in subvol=
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+[ Upstream commit 3ef3959b29c4a5bd65526ab310a1a18ae533172a ]
+
+Chris Murphy reported a problem where rpm ostree will bind mount a bunch
+of things for whatever voodoo it's doing.  But when it does this
+/proc/mounts shows something like
+
+  /dev/sda /mnt/test btrfs rw,relatime,subvolid=256,subvol=/foo 0 0
+  /dev/sda /mnt/test/baz btrfs rw,relatime,subvolid=256,subvol=/foo/bar 0 0
+
+Despite subvolid=256 being subvol=/foo.  This is because we're just
+spitting out the dentry of the mount point, which in the case of bind
+mounts is the source path for the mountpoint.  Instead we should spit
+out the path to the actual subvol.  Fix this by looking up the name for
+the subvolid we have mounted.  With this fix the same test looks like
+this
+
+  /dev/sda /mnt/test btrfs rw,relatime,subvolid=256,subvol=/foo 0 0
+  /dev/sda /mnt/test/baz btrfs rw,relatime,subvolid=256,subvol=/foo 0 0
+
+Reported-by: Chris Murphy <chris@colorremedies.com>
+CC: stable@vger.kernel.org # 4.4+
+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: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/super.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 32c36821cc7b4..e21cae80c6d58 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -1291,6 +1291,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
+ {
+       struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
+       const char *compress_type;
++      const char *subvol_name;
+       if (btrfs_test_opt(info, DEGRADED))
+               seq_puts(seq, ",degraded");
+@@ -1375,8 +1376,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
+               seq_puts(seq, ",ref_verify");
+       seq_printf(seq, ",subvolid=%llu",
+                 BTRFS_I(d_inode(dentry))->root->root_key.objectid);
+-      seq_puts(seq, ",subvol=");
+-      seq_dentry(seq, dentry, " \t\n\\");
++      subvol_name = btrfs_get_subvol_name_from_objectid(info,
++                      BTRFS_I(d_inode(dentry))->root->root_key.objectid);
++      if (!IS_ERR(subvol_name)) {
++              seq_puts(seq, ",subvol=");
++              seq_escape(seq, subvol_name, " \t\n\\");
++              kfree(subvol_name);
++      }
+       return 0;
+ }
+-- 
+2.25.1
+
diff --git a/queue-5.4/btrfs-export-helpers-for-subvolume-name-id-resolutio.patch b/queue-5.4/btrfs-export-helpers-for-subvolume-name-id-resolutio.patch
new file mode 100644 (file)
index 0000000..cc2d593
--- /dev/null
@@ -0,0 +1,107 @@
+From 7832dc6dfcd889648c15f43081c14ada3a7b13be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Feb 2020 14:56:12 +0100
+Subject: btrfs: export helpers for subvolume name/id resolution
+
+From: Marcos Paulo de Souza <mpdesouza@suse.com>
+
+[ Upstream commit c0c907a47dccf2cf26251a8fb4a8e7a3bf79ce84 ]
+
+The functions will be used outside of export.c and super.c to allow
+resolving subvolume name from a given id, eg. for subvolume deletion by
+id ioctl.
+
+Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+[ split from the next patch ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ctree.h  | 2 ++
+ fs/btrfs/export.c | 8 ++++----
+ fs/btrfs/export.h | 5 +++++
+ fs/btrfs/super.c  | 8 ++++----
+ 4 files changed, 15 insertions(+), 8 deletions(-)
+
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 2374f3f6f3b70..18357b054a91e 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2965,6 +2965,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
+ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
+                       unsigned long new_flags);
+ int btrfs_sync_fs(struct super_block *sb, int wait);
++char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
++                                        u64 subvol_objectid);
+ static inline __printf(2, 3) __cold
+ void btrfs_no_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
+diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
+index ddf28ecf17f93..93cceeba484cc 100644
+--- a/fs/btrfs/export.c
++++ b/fs/btrfs/export.c
+@@ -57,9 +57,9 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
+       return type;
+ }
+-static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
+-                                     u64 root_objectid, u32 generation,
+-                                     int check_generation)
++struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
++                              u64 root_objectid, u32 generation,
++                              int check_generation)
+ {
+       struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+       struct btrfs_root *root;
+@@ -152,7 +152,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
+       return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1);
+ }
+-static struct dentry *btrfs_get_parent(struct dentry *child)
++struct dentry *btrfs_get_parent(struct dentry *child)
+ {
+       struct inode *dir = d_inode(child);
+       struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
+diff --git a/fs/btrfs/export.h b/fs/btrfs/export.h
+index 57488ecd7d4ef..f32f4113c976a 100644
+--- a/fs/btrfs/export.h
++++ b/fs/btrfs/export.h
+@@ -18,4 +18,9 @@ struct btrfs_fid {
+       u64 parent_root_objectid;
+ } __attribute__ ((packed));
++struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid,
++                              u64 root_objectid, u32 generation,
++                              int check_generation);
++struct dentry *btrfs_get_parent(struct dentry *child);
++
+ #endif
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 4b0ee34aa65d5..32c36821cc7b4 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -1009,8 +1009,8 @@ out:
+       return error;
+ }
+-static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
+-                                         u64 subvol_objectid)
++char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info,
++                                        u64 subvol_objectid)
+ {
+       struct btrfs_root *root = fs_info->tree_root;
+       struct btrfs_root *fs_root;
+@@ -1421,8 +1421,8 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid,
+                               goto out;
+                       }
+               }
+-              subvol_name = get_subvol_name_from_objectid(btrfs_sb(mnt->mnt_sb),
+-                                                          subvol_objectid);
++              subvol_name = btrfs_get_subvol_name_from_objectid(
++                                      btrfs_sb(mnt->mnt_sb), subvol_objectid);
+               if (IS_ERR(subvol_name)) {
+                       root = ERR_CAST(subvol_name);
+                       subvol_name = NULL;
+-- 
+2.25.1
+
diff --git a/queue-5.4/btrfs-return-erofs-for-btrfs_fs_state_error-cases.patch b/queue-5.4/btrfs-return-erofs-for-btrfs_fs_state_error-cases.patch
new file mode 100644 (file)
index 0000000..e0c3402
--- /dev/null
@@ -0,0 +1,157 @@
+From 1c53e6f5d30a6ac96087ab28523115bdae03921f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Jul 2020 10:38:37 -0400
+Subject: btrfs: return EROFS for BTRFS_FS_STATE_ERROR cases
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+Eric reported seeing this message while running generic/475
+
+  BTRFS: error (device dm-3) in btrfs_sync_log:3084: errno=-117 Filesystem corrupted
+
+Full stack trace:
+
+  BTRFS: error (device dm-0) in btrfs_commit_transaction:2323: errno=-5 IO failure (Error while writing out transaction)
+  BTRFS info (device dm-0): forced readonly
+  BTRFS warning (device dm-0): Skipping commit of aborted transaction.
+  ------------[ cut here ]------------
+  BTRFS: error (device dm-0) in cleanup_transaction:1894: errno=-5 IO failure
+  BTRFS: Transaction aborted (error -117)
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c6480 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c6488 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c6490 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c6498 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c64a0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c64a8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c64b0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c64b8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3555 rw 0,0 sector 0x1c64c0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3572 rw 0,0 sector 0x1b85e8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3572 rw 0,0 sector 0x1b85f0 len 4096 err no 10
+  WARNING: CPU: 3 PID: 23985 at fs/btrfs/tree-log.c:3084 btrfs_sync_log+0xbc8/0xd60 [btrfs]
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d4288 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d4290 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d4298 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42a0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42a8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42b0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42b8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42c0 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42c8 len 4096 err no 10
+  BTRFS warning (device dm-0): direct IO failed ino 3548 rw 0,0 sector 0x1d42d0 len 4096 err no 10
+  CPU: 3 PID: 23985 Comm: fsstress Tainted: G        W    L    5.8.0-rc4-default+ #1181
+  Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba527-rebuilt.opensuse.org 04/01/2014
+  RIP: 0010:btrfs_sync_log+0xbc8/0xd60 [btrfs]
+  RSP: 0018:ffff909a44d17bd0 EFLAGS: 00010286
+  RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000001
+  RDX: ffff8f3be41cb940 RSI: ffffffffb0108d2b RDI: ffffffffb0108ff7
+  RBP: ffff909a44d17e70 R08: 0000000000000000 R09: 0000000000000000
+  R10: 0000000000000000 R11: 0000000000037988 R12: ffff8f3bd20e4000
+  R13: ffff8f3bd20e4428 R14: 00000000ffffff8b R15: ffff909a44d17c70
+  FS:  00007f6a6ed3fb80(0000) GS:ffff8f3c3dc00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00007f6a6ed3e000 CR3: 00000000525c0003 CR4: 0000000000160ee0
+  Call Trace:
+   ? finish_wait+0x90/0x90
+   ? __mutex_unlock_slowpath+0x45/0x2a0
+   ? lock_acquire+0xa3/0x440
+   ? lockref_put_or_lock+0x9/0x30
+   ? dput+0x20/0x4a0
+   ? dput+0x20/0x4a0
+   ? do_raw_spin_unlock+0x4b/0xc0
+   ? _raw_spin_unlock+0x1f/0x30
+   btrfs_sync_file+0x335/0x490 [btrfs]
+   do_fsync+0x38/0x70
+   __x64_sys_fsync+0x10/0x20
+   do_syscall_64+0x50/0xe0
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  RIP: 0033:0x7f6a6ef1b6e3
+  Code: Bad RIP value.
+  RSP: 002b:00007ffd01e20038 EFLAGS: 00000246 ORIG_RAX: 000000000000004a
+  RAX: ffffffffffffffda RBX: 000000000007a120 RCX: 00007f6a6ef1b6e3
+  RDX: 00007ffd01e1ffa0 RSI: 00007ffd01e1ffa0 RDI: 0000000000000003
+  RBP: 0000000000000003 R08: 0000000000000001 R09: 00007ffd01e2004c
+  R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000009f
+  R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+  irq event stamp: 0
+  hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+  hardirqs last disabled at (0): [<ffffffffb007fe0b>] copy_process+0x67b/0x1b00
+  softirqs last  enabled at (0): [<ffffffffb007fe0b>] copy_process+0x67b/0x1b00
+  softirqs last disabled at (0): [<0000000000000000>] 0x0
+  ---[ end trace af146e0e38433456 ]---
+  BTRFS: error (device dm-0) in btrfs_sync_log:3084: errno=-117 Filesystem corrupted
+
+This ret came from btrfs_write_marked_extents().  If we get an aborted
+transaction via EIO before, we'll see it in btree_write_cache_pages()
+and return EUCLEAN, which gets printed as "Filesystem corrupted".
+
+Except we shouldn't be returning EUCLEAN here, we need to be returning
+EROFS because EUCLEAN is reserved for actual corruption, not IO errors.
+
+We are inconsistent about our handling of BTRFS_FS_STATE_ERROR
+elsewhere, but we want to use EROFS for this particular case.  The
+original transaction abort has the real error code for why we ended up
+with an aborted transaction, all subsequent actions just need to return
+EROFS because they may not have a trans handle and have no idea about
+the original cause of the abort.
+
+After patch "btrfs: don't WARN if we abort a transaction with EROFS" the
+stacktrace will not be dumped either.
+
+Reported-by: Eric Sandeen <esandeen@redhat.com>
+CC: stable@vger.kernel.org # 5.4+
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+[ add full test stacktrace ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+---
+ fs/btrfs/extent_io.c   | 2 +-
+ fs/btrfs/scrub.c       | 2 +-
+ fs/btrfs/transaction.c | 5 ++++-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 035ea5bc692ad..5707bf0575d43 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -4073,7 +4073,7 @@ retry:
+       if (!test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
+               ret = flush_write_bio(&epd);
+       } else {
+-              ret = -EUCLEAN;
++              ret = -EROFS;
+               end_write_bio(&epd, ret);
+       }
+       return ret;
+diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
+index a7b043fd7a572..498b824148187 100644
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3717,7 +3717,7 @@ static noinline_for_stack int scrub_supers(struct scrub_ctx *sctx,
+       struct btrfs_fs_info *fs_info = sctx->fs_info;
+       if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state))
+-              return -EIO;
++              return -EROFS;
+       /* Seed devices of a new filesystem has their own generation. */
+       if (scrub_dev->fs_devices != fs_info->fs_devices)
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index 54589e940f9af..465ddb297c381 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -873,7 +873,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
+       if (trans->aborted ||
+           test_bit(BTRFS_FS_STATE_ERROR, &info->fs_state)) {
+               wake_up_process(info->transaction_kthread);
+-              err = -EIO;
++              if (TRANS_ABORTED(trans))
++                      err = trans->aborted;
++              else
++                      err = -EROFS;
+       }
+       kmem_cache_free(btrfs_trans_handle_cachep, trans);
+-- 
+2.25.1
+
diff --git a/queue-5.4/drm-vgem-replace-opencoded-version-of-drm_gem_dumb_m.patch b/queue-5.4/drm-vgem-replace-opencoded-version-of-drm_gem_dumb_m.patch
new file mode 100644 (file)
index 0000000..0e678a8
--- /dev/null
@@ -0,0 +1,83 @@
+From fbc3cd1cc3189cedb14d7a87eb2b4df940250814 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Jul 2020 16:49:11 +0100
+Subject: drm/vgem: Replace opencoded version of drm_gem_dumb_map_offset()
+
+From: Chris Wilson <chris@chris-wilson.co.uk>
+
+[ Upstream commit 119c53d2d4044c59c450c4f5a568d80b9d861856 ]
+
+drm_gem_dumb_map_offset() now exists and does everything
+vgem_gem_dump_map does and *ought* to do.
+
+In particular, vgem_gem_dumb_map() was trying to reject mmapping an
+imported dmabuf by checking the existence of obj->filp. Unfortunately,
+we always allocated an obj->filp, even if unused for an imported dmabuf.
+Instead, the drm_gem_dumb_map_offset(), since commit 90378e589192
+("drm/gem: drm_gem_dumb_map_offset(): reject dma-buf"), uses the
+obj->import_attach to reject such invalid mmaps.
+
+This prevents vgem from allowing userspace mmapping the dumb handle and
+attempting to incorrectly fault in remote pages belonging to another
+device, where there may not even be a struct page.
+
+v2: Use the default drm_gem_dumb_map_offset() callback
+
+Fixes: af33a9190d02 ("drm/vgem: Enable dmabuf import interfaces")
+Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
+Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: <stable@vger.kernel.org> # v4.13+
+Link: https://patchwork.freedesktop.org/patch/msgid/20200708154911.21236-1-chris@chris-wilson.co.uk
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vgem/vgem_drv.c | 27 ---------------------------
+ 1 file changed, 27 deletions(-)
+
+diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
+index 909eba43664a2..204d1df5a21d1 100644
+--- a/drivers/gpu/drm/vgem/vgem_drv.c
++++ b/drivers/gpu/drm/vgem/vgem_drv.c
+@@ -229,32 +229,6 @@ static int vgem_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+       return 0;
+ }
+-static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
+-                           uint32_t handle, uint64_t *offset)
+-{
+-      struct drm_gem_object *obj;
+-      int ret;
+-
+-      obj = drm_gem_object_lookup(file, handle);
+-      if (!obj)
+-              return -ENOENT;
+-
+-      if (!obj->filp) {
+-              ret = -EINVAL;
+-              goto unref;
+-      }
+-
+-      ret = drm_gem_create_mmap_offset(obj);
+-      if (ret)
+-              goto unref;
+-
+-      *offset = drm_vma_node_offset_addr(&obj->vma_node);
+-unref:
+-      drm_gem_object_put_unlocked(obj);
+-
+-      return ret;
+-}
+-
+ static struct drm_ioctl_desc vgem_ioctls[] = {
+       DRM_IOCTL_DEF_DRV(VGEM_FENCE_ATTACH, vgem_fence_attach_ioctl, DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF_DRV(VGEM_FENCE_SIGNAL, vgem_fence_signal_ioctl, DRM_RENDER_ALLOW),
+@@ -448,7 +422,6 @@ static struct drm_driver vgem_driver = {
+       .fops                           = &vgem_driver_fops,
+       .dumb_create                    = vgem_gem_dumb_create,
+-      .dumb_map_offset                = vgem_gem_dumb_map,
+       .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+       .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+-- 
+2.25.1
+
diff --git a/queue-5.4/gfs2-improve-mmap-write-vs.-punch_hole-consistency.patch b/queue-5.4/gfs2-improve-mmap-write-vs.-punch_hole-consistency.patch
new file mode 100644 (file)
index 0000000..64cd51d
--- /dev/null
@@ -0,0 +1,62 @@
+From 0c722adcc833760197b3e4e59d0b73f012a22bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 6 Sep 2019 14:51:38 +0100
+Subject: gfs2: Improve mmap write vs. punch_hole consistency
+
+From: Andreas Gruenbacher <agruenba@redhat.com>
+
+[ Upstream commit 39c3a948ecf6e7b8f55f0e91a5febc924fede4d7 ]
+
+When punching a hole in a file, use filemap_write_and_wait_range to
+write back any dirty pages in the range of the hole.  As a side effect,
+if the hole isn't page aligned, this marks unaligned pages at the
+beginning and the end of the hole read-only.  This is required when the
+block size is smaller than the page size: when those pages are written
+to again after the hole punching, we must make sure that page_mkwrite is
+called for those pages so that the page will be fully allocated and any
+blocks turned into holes from the hole punching will be reallocated.
+(If a page is writably mapped, page_mkwrite won't be called.)
+
+Fixes xfstest generic/567.
+
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/bmap.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
+index adbb8fef22162..4846e0c47e6af 100644
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -2442,8 +2442,16 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
+       struct inode *inode = file_inode(file);
+       struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
++      unsigned int blocksize = i_blocksize(inode);
++      loff_t start, end;
+       int error;
++      start = round_down(offset, blocksize);
++      end = round_up(offset + length, blocksize) - 1;
++      error = filemap_write_and_wait_range(inode->i_mapping, start, end);
++      if (error)
++              return error;
++
+       if (gfs2_is_jdata(ip))
+               error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
+                                        GFS2_JTRUNC_REVOKES);
+@@ -2457,9 +2465,8 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
+               if (error)
+                       goto out;
+       } else {
+-              unsigned int start_off, end_len, blocksize;
++              unsigned int start_off, end_len;
+-              blocksize = i_blocksize(inode);
+               start_off = offset & (blocksize - 1);
+               end_len = (offset + length) & (blocksize - 1);
+               if (start_off) {
+-- 
+2.25.1
+
diff --git a/queue-5.4/gfs2-never-call-gfs2_block_zero_range-with-an-open-t.patch b/queue-5.4/gfs2-never-call-gfs2_block_zero_range-with-an-open-t.patch
new file mode 100644 (file)
index 0000000..1caa908
--- /dev/null
@@ -0,0 +1,158 @@
+From ce47414b53a0142cdfa2429fbf82c112266cecc6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jul 2020 12:06:31 -0500
+Subject: gfs2: Never call gfs2_block_zero_range with an open transaction
+
+From: Bob Peterson <rpeterso@redhat.com>
+
+[ Upstream commit 70499cdfeb3625c87eebe4f7a7ea06fa7447e5df ]
+
+Before this patch, some functions started transactions then they called
+gfs2_block_zero_range. However, gfs2_block_zero_range, like writes, can
+start transactions, which results in a recursive transaction error.
+For example:
+
+do_shrink
+   trunc_start
+      gfs2_trans_begin <------------------------------------------------
+         gfs2_block_zero_range
+            iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops);
+               iomap_apply ... iomap_zero_range_actor
+                  iomap_begin
+                     gfs2_iomap_begin
+                        gfs2_iomap_begin_write
+                  actor (iomap_zero_range_actor)
+                    iomap_zero
+                       iomap_write_begin
+                          gfs2_iomap_page_prepare
+                             gfs2_trans_begin <------------------------
+
+This patch reorders the callers of gfs2_block_zero_range so that they
+only start their transactions after the call. It also adds a BUG_ON to
+ensure this doesn't happen again.
+
+Fixes: 2257e468a63b ("gfs2: implement gfs2_block_zero_range using iomap_zero_range")
+Cc: stable@vger.kernel.org # v5.5+
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/gfs2/bmap.c | 69 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 39 insertions(+), 30 deletions(-)
+
+diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
+index 4846e0c47e6af..50fa3e08c02f3 100644
+--- a/fs/gfs2/bmap.c
++++ b/fs/gfs2/bmap.c
+@@ -1350,9 +1350,15 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi
+       return ret;
+ }
++/*
++ * NOTE: Never call gfs2_block_zero_range with an open transaction because it
++ * uses iomap write to perform its actions, which begin their own transactions
++ * (iomap_begin, page_prepare, etc.)
++ */
+ static int gfs2_block_zero_range(struct inode *inode, loff_t from,
+                                unsigned int length)
+ {
++      BUG_ON(current->journal_info);
+       return iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops);
+ }
+@@ -1413,6 +1419,16 @@ static int trunc_start(struct inode *inode, u64 newsize)
+       u64 oldsize = inode->i_size;
+       int error;
++      if (!gfs2_is_stuffed(ip)) {
++              unsigned int blocksize = i_blocksize(inode);
++              unsigned int offs = newsize & (blocksize - 1);
++              if (offs) {
++                      error = gfs2_block_zero_range(inode, newsize,
++                                                    blocksize - offs);
++                      if (error)
++                              return error;
++              }
++      }
+       if (journaled)
+               error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES);
+       else
+@@ -1426,19 +1442,10 @@ static int trunc_start(struct inode *inode, u64 newsize)
+       gfs2_trans_add_meta(ip->i_gl, dibh);
+-      if (gfs2_is_stuffed(ip)) {
++      if (gfs2_is_stuffed(ip))
+               gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + newsize);
+-      } else {
+-              unsigned int blocksize = i_blocksize(inode);
+-              unsigned int offs = newsize & (blocksize - 1);
+-              if (offs) {
+-                      error = gfs2_block_zero_range(inode, newsize,
+-                                                    blocksize - offs);
+-                      if (error)
+-                              goto out;
+-              }
++      else
+               ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG;
+-      }
+       i_size_write(inode, newsize);
+       ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
+@@ -2446,25 +2453,7 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
+       loff_t start, end;
+       int error;
+-      start = round_down(offset, blocksize);
+-      end = round_up(offset + length, blocksize) - 1;
+-      error = filemap_write_and_wait_range(inode->i_mapping, start, end);
+-      if (error)
+-              return error;
+-
+-      if (gfs2_is_jdata(ip))
+-              error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
+-                                       GFS2_JTRUNC_REVOKES);
+-      else
+-              error = gfs2_trans_begin(sdp, RES_DINODE, 0);
+-      if (error)
+-              return error;
+-
+-      if (gfs2_is_stuffed(ip)) {
+-              error = stuffed_zero_range(inode, offset, length);
+-              if (error)
+-                      goto out;
+-      } else {
++      if (!gfs2_is_stuffed(ip)) {
+               unsigned int start_off, end_len;
+               start_off = offset & (blocksize - 1);
+@@ -2487,6 +2476,26 @@ int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
+               }
+       }
++      start = round_down(offset, blocksize);
++      end = round_up(offset + length, blocksize) - 1;
++      error = filemap_write_and_wait_range(inode->i_mapping, start, end);
++      if (error)
++              return error;
++
++      if (gfs2_is_jdata(ip))
++              error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
++                                       GFS2_JTRUNC_REVOKES);
++      else
++              error = gfs2_trans_begin(sdp, RES_DINODE, 0);
++      if (error)
++              return error;
++
++      if (gfs2_is_stuffed(ip)) {
++              error = stuffed_zero_range(inode, offset, length);
++              if (error)
++                      goto out;
++      }
++
+       if (gfs2_is_jdata(ip)) {
+               BUG_ON(!current->journal_info);
+               gfs2_journaled_truncate_range(inode, offset, length);
+-- 
+2.25.1
+
diff --git a/queue-5.4/khugepaged-adjust-vm_bug_on_mm-in-__khugepaged_enter.patch b/queue-5.4/khugepaged-adjust-vm_bug_on_mm-in-__khugepaged_enter.patch
new file mode 100644 (file)
index 0000000..cbc08cd
--- /dev/null
@@ -0,0 +1,51 @@
+From 98796d4ed55b4c4f69e4dda3ef9b9409ec8b24b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Aug 2020 17:42:02 -0700
+Subject: khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter()
+
+From: Hugh Dickins <hughd@google.com>
+
+[ Upstream commit f3f99d63a8156c7a4a6b20aac22b53c5579c7dc1 ]
+
+syzbot crashes on the VM_BUG_ON_MM(khugepaged_test_exit(mm), mm) in
+__khugepaged_enter(): yes, when one thread is about to dump core, has set
+core_state, and is waiting for others, another might do something calling
+__khugepaged_enter(), which now crashes because I lumped the core_state
+test (known as "mmget_still_valid") into khugepaged_test_exit().  I still
+think it's best to lump them together, so just in this exceptional case,
+check mm->mm_users directly instead of khugepaged_test_exit().
+
+Fixes: bbe98f9cadff ("khugepaged: khugepaged_test_exit() check mmget_still_valid()")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Acked-by: Yang Shi <shy828301@gmail.com>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: <stable@vger.kernel.org>   [4.8+]
+Link: http://lkml.kernel.org/r/alpine.LSU.2.11.2008141503370.18085@eggly.anvils
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/khugepaged.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 76e3e90dbc16e..3623d1c5343f2 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -438,7 +438,7 @@ int __khugepaged_enter(struct mm_struct *mm)
+               return -ENOMEM;
+       /* __khugepaged_exit() must not run from under us */
+-      VM_BUG_ON_MM(khugepaged_test_exit(mm), mm);
++      VM_BUG_ON_MM(atomic_read(&mm->mm_users) == 0, mm);
+       if (unlikely(test_and_set_bit(MMF_VM_HUGEPAGE, &mm->flags))) {
+               free_mm_slot(mm_slot);
+               return 0;
+-- 
+2.25.1
+
diff --git a/queue-5.4/khugepaged-khugepaged_test_exit-check-mmget_still_va.patch b/queue-5.4/khugepaged-khugepaged_test_exit-check-mmget_still_va.patch
new file mode 100644 (file)
index 0000000..ad59e5d
--- /dev/null
@@ -0,0 +1,60 @@
+From 7ca98fa06d15321ccb25f256a2a90bfbe2b456b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 23:26:25 -0700
+Subject: khugepaged: khugepaged_test_exit() check mmget_still_valid()
+
+From: Hugh Dickins <hughd@google.com>
+
+[ Upstream commit bbe98f9cadff58cdd6a4acaeba0efa8565dabe65 ]
+
+Move collapse_huge_page()'s mmget_still_valid() check into
+khugepaged_test_exit() itself.  collapse_huge_page() is used for anon THP
+only, and earned its mmget_still_valid() check because it inserts a huge
+pmd entry in place of the page table's pmd entry; whereas
+collapse_file()'s retract_page_tables() or collapse_pte_mapped_thp()
+merely clears the page table's pmd entry.  But core dumping without mmap
+lock must have been as open to mistaking a racily cleared pmd entry for a
+page table at physical page 0, as exit_mmap() was.  And we certainly have
+no interest in mapping as a THP once dumping core.
+
+Fixes: 59ea6d06cfa9 ("coredump: fix race condition between collapse_huge_page() and core dumping")
+Signed-off-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Song Liu <songliubraving@fb.com>
+Cc: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Cc: <stable@vger.kernel.org>   [4.8+]
+Link: http://lkml.kernel.org/r/alpine.LSU.2.11.2008021217020.27773@eggly.anvils
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/khugepaged.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 719f49d1fba2f..76e3e90dbc16e 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -401,7 +401,7 @@ static void insert_to_mm_slots_hash(struct mm_struct *mm,
+ static inline int khugepaged_test_exit(struct mm_struct *mm)
+ {
+-      return atomic_read(&mm->mm_users) == 0;
++      return atomic_read(&mm->mm_users) == 0 || !mmget_still_valid(mm);
+ }
+ static bool hugepage_vma_check(struct vm_area_struct *vma,
+@@ -1019,9 +1019,6 @@ static void collapse_huge_page(struct mm_struct *mm,
+        * handled by the anon_vma lock + PG_lock.
+        */
+       down_write(&mm->mmap_sem);
+-      result = SCAN_ANY_PROCESS;
+-      if (!mmget_still_valid(mm))
+-              goto out;
+       result = hugepage_vma_revalidate(mm, address, &vma);
+       if (result)
+               goto out;
+-- 
+2.25.1
+
diff --git a/queue-5.4/perf-probe-fix-memory-leakage-when-the-probe-point-i.patch b/queue-5.4/perf-probe-fix-memory-leakage-when-the-probe-point-i.patch
new file mode 100644 (file)
index 0000000..834e0b9
--- /dev/null
@@ -0,0 +1,52 @@
+From 82731e6b83d69134614ca9e738a1519e3c8ad84d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2020 22:11:23 +0900
+Subject: perf probe: Fix memory leakage when the probe point is not found
+
+From: Masami Hiramatsu <mhiramat@kernel.org>
+
+[ Upstream commit 12d572e785b15bc764e956caaa8a4c846fd15694 ]
+
+Fix the memory leakage in debuginfo__find_trace_events() when the probe
+point is not found in the debuginfo. If there is no probe point found in
+the debuginfo, debuginfo__find_probes() will NOT return -ENOENT, but 0.
+
+Thus the caller of debuginfo__find_probes() must check the tf.ntevs and
+release the allocated memory for the array of struct probe_trace_event.
+
+The current code releases the memory only if the debuginfo__find_probes()
+hits an error but not checks tf.ntevs. In the result, the memory allocated
+on *tevs are not released if tf.ntevs == 0.
+
+This fixes the memory leakage by checking tf.ntevs == 0 in addition to
+ret < 0.
+
+Fixes: ff741783506c ("perf probe: Introduce debuginfo to encapsulate dwarf information")
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: stable@vger.kernel.org
+Link: http://lore.kernel.org/lkml/159438668346.62703.10887420400718492503.stgit@devnote2
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/probe-finder.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
+index dc9d495e3d6ab..849d8d2e5976b 100644
+--- a/tools/perf/util/probe-finder.c
++++ b/tools/perf/util/probe-finder.c
+@@ -1362,7 +1362,7 @@ int debuginfo__find_trace_events(struct debuginfo *dbg,
+       tf.ntevs = 0;
+       ret = debuginfo__find_probes(dbg, &tf.pf);
+-      if (ret < 0) {
++      if (ret < 0 || tf.ntevs == 0) {
+               for (i = 0; i < tf.ntevs; i++)
+                       clear_probe_trace_event(&tf.tevs[i]);
+               zfree(tevs);
+-- 
+2.25.1
+
index 7f777ddb8be275464b4ef8ba0ae435713c51e7f5..22f4382ae54775d338924c5afc2a70e65a9fddbf 100644 (file)
@@ -7,3 +7,14 @@ kbuild-remove-python2-variable.patch
 kbuild-remove-as-variable.patch
 kbuild-replace-as-clang-with-llvm_ias-1.patch
 kbuild-support-llvm-1-to-switch-the-default-tools-to-clang-llvm.patch
+drm-vgem-replace-opencoded-version-of-drm_gem_dumb_m.patch
+gfs2-improve-mmap-write-vs.-punch_hole-consistency.patch
+gfs2-never-call-gfs2_block_zero_range-with-an-open-t.patch
+perf-probe-fix-memory-leakage-when-the-probe-point-i.patch
+khugepaged-khugepaged_test_exit-check-mmget_still_va.patch
+khugepaged-adjust-vm_bug_on_mm-in-__khugepaged_enter.patch
+bcache-avoid-nr_stripes-overflow-in-bcache_device_in.patch
+btrfs-export-helpers-for-subvolume-name-id-resolutio.patch
+btrfs-don-t-show-full-path-of-bind-mounts-in-subvol.patch
+btrfs-return-erofs-for-btrfs_fs_state_error-cases.patch
+btrfs-add-wrapper-for-transaction-abort-predicate.patch