--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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