--- /dev/null
+From fccc0007b8dc952c6bc0805cdf842eb8ea06a639 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <josef@toxicpanda.com>
+Date: Mon, 31 Aug 2020 10:52:42 -0400
+Subject: btrfs: fix lockdep splat in add_missing_dev
+
+From: Josef Bacik <josef@toxicpanda.com>
+
+commit fccc0007b8dc952c6bc0805cdf842eb8ea06a639 upstream.
+
+Nikolay reported a lockdep splat in generic/476 that I could reproduce
+with btrfs/187.
+
+ ======================================================
+ WARNING: possible circular locking dependency detected
+ 5.9.0-rc2+ #1 Tainted: G W
+ ------------------------------------------------------
+ kswapd0/100 is trying to acquire lock:
+ ffff9e8ef38b6268 (&delayed_node->mutex){+.+.}-{3:3}, at: __btrfs_release_delayed_node.part.0+0x3f/0x330
+
+ but task is already holding lock:
+ ffffffffa9d74700 (fs_reclaim){+.+.}-{0:0}, at: __fs_reclaim_acquire+0x5/0x30
+
+ which lock already depends on the new lock.
+
+ the existing dependency chain (in reverse order) is:
+
+ -> #2 (fs_reclaim){+.+.}-{0:0}:
+ fs_reclaim_acquire+0x65/0x80
+ slab_pre_alloc_hook.constprop.0+0x20/0x200
+ kmem_cache_alloc_trace+0x3a/0x1a0
+ btrfs_alloc_device+0x43/0x210
+ add_missing_dev+0x20/0x90
+ read_one_chunk+0x301/0x430
+ btrfs_read_sys_array+0x17b/0x1b0
+ open_ctree+0xa62/0x1896
+ btrfs_mount_root.cold+0x12/0xea
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ vfs_kern_mount.part.0+0x71/0xb0
+ btrfs_mount+0x10d/0x379
+ legacy_get_tree+0x30/0x50
+ vfs_get_tree+0x28/0xc0
+ path_mount+0x434/0xc00
+ __x64_sys_mount+0xe3/0x120
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #1 (&fs_info->chunk_mutex){+.+.}-{3:3}:
+ __mutex_lock+0x7e/0x7e0
+ btrfs_chunk_alloc+0x125/0x3a0
+ find_free_extent+0xdf6/0x1210
+ btrfs_reserve_extent+0xb3/0x1b0
+ btrfs_alloc_tree_block+0xb0/0x310
+ alloc_tree_block_no_bg_flush+0x4a/0x60
+ __btrfs_cow_block+0x11a/0x530
+ btrfs_cow_block+0x104/0x220
+ btrfs_search_slot+0x52e/0x9d0
+ btrfs_lookup_inode+0x2a/0x8f
+ __btrfs_update_delayed_inode+0x80/0x240
+ btrfs_commit_inode_delayed_inode+0x119/0x120
+ btrfs_evict_inode+0x357/0x500
+ evict+0xcf/0x1f0
+ vfs_rmdir.part.0+0x149/0x160
+ do_rmdir+0x136/0x1a0
+ do_syscall_64+0x33/0x40
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+ -> #0 (&delayed_node->mutex){+.+.}-{3:3}:
+ __lock_acquire+0x1184/0x1fa0
+ lock_acquire+0xa4/0x3d0
+ __mutex_lock+0x7e/0x7e0
+ __btrfs_release_delayed_node.part.0+0x3f/0x330
+ btrfs_evict_inode+0x24c/0x500
+ evict+0xcf/0x1f0
+ dispose_list+0x48/0x70
+ prune_icache_sb+0x44/0x50
+ super_cache_scan+0x161/0x1e0
+ do_shrink_slab+0x178/0x3c0
+ shrink_slab+0x17c/0x290
+ shrink_node+0x2b2/0x6d0
+ balance_pgdat+0x30a/0x670
+ kswapd+0x213/0x4c0
+ kthread+0x138/0x160
+ ret_from_fork+0x1f/0x30
+
+ other info that might help us debug this:
+
+ Chain exists of:
+ &delayed_node->mutex --> &fs_info->chunk_mutex --> fs_reclaim
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(fs_reclaim);
+ lock(&fs_info->chunk_mutex);
+ lock(fs_reclaim);
+ lock(&delayed_node->mutex);
+
+ *** DEADLOCK ***
+
+ 3 locks held by kswapd0/100:
+ #0: ffffffffa9d74700 (fs_reclaim){+.+.}-{0:0}, at: __fs_reclaim_acquire+0x5/0x30
+ #1: ffffffffa9d65c50 (shrinker_rwsem){++++}-{3:3}, at: shrink_slab+0x115/0x290
+ #2: ffff9e8e9da260e0 (&type->s_umount_key#48){++++}-{3:3}, at: super_cache_scan+0x38/0x1e0
+
+ stack backtrace:
+ CPU: 1 PID: 100 Comm: kswapd0 Tainted: G W 5.9.0-rc2+ #1
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014
+ Call Trace:
+ dump_stack+0x92/0xc8
+ check_noncircular+0x12d/0x150
+ __lock_acquire+0x1184/0x1fa0
+ lock_acquire+0xa4/0x3d0
+ ? __btrfs_release_delayed_node.part.0+0x3f/0x330
+ __mutex_lock+0x7e/0x7e0
+ ? __btrfs_release_delayed_node.part.0+0x3f/0x330
+ ? __btrfs_release_delayed_node.part.0+0x3f/0x330
+ ? lock_acquire+0xa4/0x3d0
+ ? btrfs_evict_inode+0x11e/0x500
+ ? find_held_lock+0x2b/0x80
+ __btrfs_release_delayed_node.part.0+0x3f/0x330
+ btrfs_evict_inode+0x24c/0x500
+ evict+0xcf/0x1f0
+ dispose_list+0x48/0x70
+ prune_icache_sb+0x44/0x50
+ super_cache_scan+0x161/0x1e0
+ do_shrink_slab+0x178/0x3c0
+ shrink_slab+0x17c/0x290
+ shrink_node+0x2b2/0x6d0
+ balance_pgdat+0x30a/0x670
+ kswapd+0x213/0x4c0
+ ? _raw_spin_unlock_irqrestore+0x46/0x60
+ ? add_wait_queue_exclusive+0x70/0x70
+ ? balance_pgdat+0x670/0x670
+ kthread+0x138/0x160
+ ? kthread_create_worker_on_cpu+0x40/0x40
+ ret_from_fork+0x1f/0x30
+
+This is because we are holding the chunk_mutex when we call
+btrfs_alloc_device, which does a GFP_KERNEL allocation. We don't want
+to switch that to a GFP_NOFS lock because this is the only place where
+it matters. So instead use memalloc_nofs_save() around the allocation
+in order to avoid the lockdep splat.
+
+Reported-by: Nikolay Borisov <nborisov@suse.com>
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Anand Jain <anand.jain@oracle.com>
+Signed-off-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -16,6 +16,7 @@
+ * Boston, MA 021110-1307, USA.
+ */
+ #include <linux/sched.h>
++#include <linux/sched/mm.h>
+ #include <linux/bio.h>
+ #include <linux/slab.h>
+ #include <linux/buffer_head.h>
+@@ -6278,8 +6279,17 @@ static struct btrfs_device *add_missing_
+ u64 devid, u8 *dev_uuid)
+ {
+ struct btrfs_device *device;
++ unsigned int nofs_flag;
+
++ /*
++ * We call this under the chunk_mutex, so we want to use NOFS for this
++ * allocation, however we don't want to change btrfs_alloc_device() to
++ * always do NOFS because we use it in a lot of other GFP_KERNEL safe
++ * places.
++ */
++ nofs_flag = memalloc_nofs_save();
+ device = btrfs_alloc_device(NULL, &devid, dev_uuid);
++ memalloc_nofs_restore(nofs_flag);
+ if (IS_ERR(device))
+ return NULL;
+
--- /dev/null
+From 1c78544eaa4660096aeb6a57ec82b42cdb3bfe5a Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 14 Sep 2020 09:01:04 +0100
+Subject: btrfs: fix wrong address when faulting in pages in the search ioctl
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 1c78544eaa4660096aeb6a57ec82b42cdb3bfe5a upstream.
+
+When faulting in the pages for the user supplied buffer for the search
+ioctl, we are passing only the base address of the buffer to the function
+fault_in_pages_writeable(). This means that after the first iteration of
+the while loop that searches for leaves, when we have a non-zero offset,
+stored in 'sk_offset', we try to fault in a wrong page range.
+
+So fix this by adding the offset in 'sk_offset' to the base address of the
+user supplied buffer when calling fault_in_pages_writeable().
+
+Several users have reported that the applications compsize and bees have
+started to operate incorrectly since commit a48b73eca4ceb9 ("btrfs: fix
+potential deadlock in the search ioctl") was added to stable trees, and
+these applications make heavy use of the search ioctls. This fixes their
+issues.
+
+Link: https://lore.kernel.org/linux-btrfs/632b888d-a3c3-b085-cdf5-f9bb61017d92@lechevalier.se/
+Link: https://github.com/kilobyte/compsize/issues/34
+Fixes: a48b73eca4ceb9 ("btrfs: fix potential deadlock in the search ioctl")
+CC: stable@vger.kernel.org # 4.4+
+Tested-by: A L <mail@lechevalier.se>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ioctl.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -2131,7 +2131,8 @@ static noinline int search_ioctl(struct
+ key.offset = sk->min_offset;
+
+ while (1) {
+- ret = fault_in_pages_writeable(ubuf, *buf_size - sk_offset);
++ ret = fault_in_pages_writeable(ubuf + sk_offset,
++ *buf_size - sk_offset);
+ if (ret)
+ break;
+
--- /dev/null
+From ea57788eb76dc81f6003245427356a1dcd0ac524 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Wed, 26 Aug 2020 17:26:43 +0800
+Subject: btrfs: require only sector size alignment for parent eb bytenr
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit ea57788eb76dc81f6003245427356a1dcd0ac524 upstream.
+
+[BUG]
+A completely sane converted fs will cause kernel warning at balance
+time:
+
+ [ 1557.188633] BTRFS info (device sda7): relocating block group 8162107392 flags data
+ [ 1563.358078] BTRFS info (device sda7): found 11722 extents
+ [ 1563.358277] BTRFS info (device sda7): leaf 7989321728 gen 95 total ptrs 213 free space 3458 owner 2
+ [ 1563.358280] item 0 key (7984947200 169 0) itemoff 16250 itemsize 33
+ [ 1563.358281] extent refs 1 gen 90 flags 2
+ [ 1563.358282] ref#0: tree block backref root 4
+ [ 1563.358285] item 1 key (7985602560 169 0) itemoff 16217 itemsize 33
+ [ 1563.358286] extent refs 1 gen 93 flags 258
+ [ 1563.358287] ref#0: shared block backref parent 7985602560
+ [ 1563.358288] (parent 7985602560 is NOT ALIGNED to nodesize 16384)
+ [ 1563.358290] item 2 key (7985635328 169 0) itemoff 16184 itemsize 33
+ ...
+ [ 1563.358995] BTRFS error (device sda7): eb 7989321728 invalid extent inline ref type 182
+ [ 1563.358996] ------------[ cut here ]------------
+ [ 1563.359005] WARNING: CPU: 14 PID: 2930 at 0xffffffff9f231766
+
+Then with transaction abort, and obviously failed to balance the fs.
+
+[CAUSE]
+That mentioned inline ref type 182 is completely sane, it's
+BTRFS_SHARED_BLOCK_REF_KEY, it's some extra check making kernel to
+believe it's invalid.
+
+Commit 64ecdb647ddb ("Btrfs: add one more sanity check for shared ref
+type") introduced extra checks for backref type.
+
+One of the requirement is, parent bytenr must be aligned to node size,
+which is not correct.
+
+One example is like this:
+
+0 1G 1G+4K 2G 2G+4K
+ | |///////////////////|//| <- A chunk starts at 1G+4K
+ | | <- A tree block get reserved at bytenr 1G+4K
+
+Then we have a valid tree block at bytenr 1G+4K, but not aligned to
+nodesize (16K).
+
+Such chunk is not ideal, but current kernel can handle it pretty well.
+We may warn about such tree block in the future, but should not reject
+them.
+
+[FIX]
+Change the alignment requirement from node size alignment to sector size
+alignment.
+
+Also, to make our lives a little easier, also output @iref when
+btrfs_get_extent_inline_ref_type() failed, so we can locate the item
+easier.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=205475
+Fixes: 64ecdb647ddb ("Btrfs: add one more sanity check for shared ref type")
+CC: stable@vger.kernel.org # 4.14+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+[ update comments and messages ]
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 19 +++++++++----------
+ fs/btrfs/print-tree.c | 12 +++++++-----
+ 2 files changed, 16 insertions(+), 15 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -1170,12 +1170,11 @@ int btrfs_get_extent_inline_ref_type(con
+ if (type == BTRFS_SHARED_BLOCK_REF_KEY) {
+ ASSERT(eb->fs_info);
+ /*
+- * Every shared one has parent tree
+- * block, which must be aligned to
+- * nodesize.
++ * Every shared one has parent tree block,
++ * which must be aligned to sector size.
+ */
+ if (offset &&
+- IS_ALIGNED(offset, eb->fs_info->nodesize))
++ IS_ALIGNED(offset, eb->fs_info->sectorsize))
+ return type;
+ }
+ } else if (is_data == BTRFS_REF_TYPE_DATA) {
+@@ -1184,12 +1183,11 @@ int btrfs_get_extent_inline_ref_type(con
+ if (type == BTRFS_SHARED_DATA_REF_KEY) {
+ ASSERT(eb->fs_info);
+ /*
+- * Every shared one has parent tree
+- * block, which must be aligned to
+- * nodesize.
++ * Every shared one has parent tree block,
++ * which must be aligned to sector size.
+ */
+ if (offset &&
+- IS_ALIGNED(offset, eb->fs_info->nodesize))
++ IS_ALIGNED(offset, eb->fs_info->sectorsize))
+ return type;
+ }
+ } else {
+@@ -1199,8 +1197,9 @@ int btrfs_get_extent_inline_ref_type(con
+ }
+
+ btrfs_print_leaf((struct extent_buffer *)eb);
+- btrfs_err(eb->fs_info, "eb %llu invalid extent inline ref type %d",
+- eb->start, type);
++ btrfs_err(eb->fs_info,
++ "eb %llu iref 0x%lx invalid extent inline ref type %d",
++ eb->start, (unsigned long)iref, type);
+ WARN_ON(1);
+
+ return BTRFS_REF_TYPE_INVALID;
+--- a/fs/btrfs/print-tree.c
++++ b/fs/btrfs/print-tree.c
+@@ -116,9 +116,10 @@ static void print_extent_item(struct ext
+ * offset is supposed to be a tree block which
+ * must be aligned to nodesize.
+ */
+- if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
+- pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
+- offset, (unsigned long long)eb->fs_info->nodesize);
++ if (!IS_ALIGNED(offset, eb->fs_info->sectorsize))
++ pr_info(
++ "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
++ offset, eb->fs_info->sectorsize);
+ break;
+ case BTRFS_EXTENT_DATA_REF_KEY:
+ dref = (struct btrfs_extent_data_ref *)(&iref->offset);
+@@ -133,8 +134,9 @@ static void print_extent_item(struct ext
+ * must be aligned to nodesize.
+ */
+ if (!IS_ALIGNED(offset, eb->fs_info->nodesize))
+- pr_info("\t\t\t(parent %llu is NOT ALIGNED to nodesize %llu)\n",
+- offset, (unsigned long long)eb->fs_info->nodesize);
++ pr_info(
++ "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
++ offset, eb->fs_info->sectorsize);
+ break;
+ default:
+ pr_cont("(extent %llu has INVALID ref type %d)\n",
--- /dev/null
+From 5c06540165d443c6455123eb48e7f1a9b618ab34 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= <mirq-linux@rere.qmqm.pl>
+Date: Wed, 12 Aug 2020 03:31:36 +0200
+Subject: regulator: push allocation in set_consumer_device_supply() out of lock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+
+commit 5c06540165d443c6455123eb48e7f1a9b618ab34 upstream.
+
+Pull regulator_list_mutex into set_consumer_device_supply() and keep
+allocations outside of it. Fourth of the fs_reclaim deadlock case.
+
+Fixes: 45389c47526d ("regulator: core: Add early supply resolution for regulators")
+Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/f0380bdb3d60aeefa9693c4e234d2dcda7e56747.1597195321.git.mirq-linux@rere.qmqm.pl
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/regulator/core.c | 46 ++++++++++++++++++++++++++--------------------
+ 1 file changed, 26 insertions(+), 20 deletions(-)
+
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -1192,7 +1192,7 @@ static int set_consumer_device_supply(st
+ const char *consumer_dev_name,
+ const char *supply)
+ {
+- struct regulator_map *node;
++ struct regulator_map *node, *new_node;
+ int has_dev;
+
+ if (supply == NULL)
+@@ -1203,6 +1203,22 @@ static int set_consumer_device_supply(st
+ else
+ has_dev = 0;
+
++ new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
++ if (new_node == NULL)
++ return -ENOMEM;
++
++ new_node->regulator = rdev;
++ new_node->supply = supply;
++
++ if (has_dev) {
++ new_node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
++ if (new_node->dev_name == NULL) {
++ kfree(new_node);
++ return -ENOMEM;
++ }
++ }
++
++ mutex_lock(®ulator_list_mutex);
+ list_for_each_entry(node, ®ulator_map_list, list) {
+ if (node->dev_name && consumer_dev_name) {
+ if (strcmp(node->dev_name, consumer_dev_name) != 0)
+@@ -1220,26 +1236,19 @@ static int set_consumer_device_supply(st
+ node->regulator->desc->name,
+ supply,
+ dev_name(&rdev->dev), rdev_get_name(rdev));
+- return -EBUSY;
++ goto fail;
+ }
+
+- node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL);
+- if (node == NULL)
+- return -ENOMEM;
+-
+- node->regulator = rdev;
+- node->supply = supply;
+-
+- if (has_dev) {
+- node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL);
+- if (node->dev_name == NULL) {
+- kfree(node);
+- return -ENOMEM;
+- }
+- }
++ list_add(&new_node->list, ®ulator_map_list);
++ mutex_unlock(®ulator_list_mutex);
+
+- list_add(&node->list, ®ulator_map_list);
+ return 0;
++
++fail:
++ mutex_unlock(®ulator_list_mutex);
++ kfree(new_node->dev_name);
++ kfree(new_node);
++ return -EBUSY;
+ }
+
+ static void unset_regulator_supplies(struct regulator_dev *rdev)
+@@ -4095,19 +4104,16 @@ regulator_register(const struct regulato
+
+ /* add consumers devices */
+ if (init_data) {
+- mutex_lock(®ulator_list_mutex);
+ for (i = 0; i < init_data->num_consumer_supplies; i++) {
+ ret = set_consumer_device_supply(rdev,
+ init_data->consumer_supplies[i].dev_name,
+ init_data->consumer_supplies[i].supply);
+ if (ret < 0) {
+- mutex_unlock(®ulator_list_mutex);
+ dev_err(dev, "Failed to set supply %s\n",
+ init_data->consumer_supplies[i].supply);
+ goto unset_supplies;
+ }
+ }
+- mutex_unlock(®ulator_list_mutex);
+ }
+
+ if (!rdev->desc->ops->get_voltage &&
--- /dev/null
+From 5528d03183fe5243416c706f64b1faa518b05130 Mon Sep 17 00:00:00 2001
+From: Varun Prakash <varun@chelsio.com>
+Date: Tue, 25 Aug 2020 18:05:10 +0530
+Subject: scsi: target: iscsi: Fix data digest calculation
+
+From: Varun Prakash <varun@chelsio.com>
+
+commit 5528d03183fe5243416c706f64b1faa518b05130 upstream.
+
+Current code does not consider 'page_off' in data digest calculation. To
+fix this, add a local variable 'first_sg' and set first_sg.offset to
+sg->offset + page_off.
+
+Link: https://lore.kernel.org/r/1598358910-3052-1-git-send-email-varun@chelsio.com
+Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Mike Christie <michael.christie@oralce.com>
+Signed-off-by: Varun Prakash <varun@chelsio.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -1382,14 +1382,27 @@ static u32 iscsit_do_crypto_hash_sg(
+ sg = cmd->first_data_sg;
+ page_off = cmd->first_data_sg_off;
+
++ if (data_length && page_off) {
++ struct scatterlist first_sg;
++ u32 len = min_t(u32, data_length, sg->length - page_off);
++
++ sg_init_table(&first_sg, 1);
++ sg_set_page(&first_sg, sg_page(sg), len, sg->offset + page_off);
++
++ ahash_request_set_crypt(hash, &first_sg, NULL, len);
++ crypto_ahash_update(hash);
++
++ data_length -= len;
++ sg = sg_next(sg);
++ }
++
+ while (data_length) {
+- u32 cur_len = min_t(u32, data_length, (sg->length - page_off));
++ u32 cur_len = min_t(u32, data_length, sg->length);
+
+ ahash_request_set_crypt(hash, sg, NULL, cur_len);
+ crypto_ahash_update(hash);
+
+ data_length -= cur_len;
+- page_off = 0;
+ /* iscsit_map_iovec has already checked for invalid sg pointers */
+ sg = sg_next(sg);
+ }
--- /dev/null
+From ed43ffea78dcc97db3f561da834f1a49c8961e33 Mon Sep 17 00:00:00 2001
+From: Hou Pu <houpu@bytedance.com>
+Date: Wed, 29 Jul 2020 09:03:43 -0400
+Subject: scsi: target: iscsi: Fix hang in iscsit_access_np() when getting tpg->np_login_sem
+
+From: Hou Pu <houpu@bytedance.com>
+
+commit ed43ffea78dcc97db3f561da834f1a49c8961e33 upstream.
+
+The iSCSI target login thread might get stuck with the following stack:
+
+cat /proc/`pidof iscsi_np`/stack
+[<0>] down_interruptible+0x42/0x50
+[<0>] iscsit_access_np+0xe3/0x167
+[<0>] iscsi_target_locate_portal+0x695/0x8ac
+[<0>] __iscsi_target_login_thread+0x855/0xb82
+[<0>] iscsi_target_login_thread+0x2f/0x5a
+[<0>] kthread+0xfa/0x130
+[<0>] ret_from_fork+0x1f/0x30
+
+This can be reproduced via the following steps:
+
+1. Initiator A tries to log in to iqn1-tpg1 on port 3260. After finishing
+ PDU exchange in the login thread and before the negotiation is finished
+ the the network link goes down. At this point A has not finished login
+ and tpg->np_login_sem is held.
+
+2. Initiator B tries to log in to iqn2-tpg1 on port 3260. After finishing
+ PDU exchange in the login thread the target expects to process remaining
+ login PDUs in workqueue context.
+
+3. Initiator A' tries to log in to iqn1-tpg1 on port 3260 from a new
+ socket. A' will wait for tpg->np_login_sem with np->np_login_timer
+ loaded to wait for at most 15 seconds. The lock is held by A so A'
+ eventually times out.
+
+4. Before A' got timeout initiator B gets negotiation failed and calls
+ iscsi_target_login_drop()->iscsi_target_login_sess_out(). The
+ np->np_login_timer is canceled and initiator A' will hang forever.
+ Because A' is now in the login thread, no new login requests can be
+ serviced.
+
+Fix this by moving iscsi_stop_login_thread_timer() out of
+iscsi_target_login_sess_out(). Also remove iscsi_np parameter from
+iscsi_target_login_sess_out().
+
+Link: https://lore.kernel.org/r/20200729130343.24976-1-houpu@bytedance.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Hou Pu <houpu@bytedance.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/iscsi/iscsi_target_login.c | 6 +++---
+ drivers/target/iscsi/iscsi_target_login.h | 3 +--
+ drivers/target/iscsi/iscsi_target_nego.c | 3 +--
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target_login.c
++++ b/drivers/target/iscsi/iscsi_target_login.c
+@@ -1158,7 +1158,7 @@ iscsit_conn_set_transport(struct iscsi_c
+ }
+
+ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
+- struct iscsi_np *np, bool zero_tsih, bool new_sess)
++ bool zero_tsih, bool new_sess)
+ {
+ if (!new_sess)
+ goto old_sess_out;
+@@ -1180,7 +1180,6 @@ void iscsi_target_login_sess_out(struct
+ conn->sess = NULL;
+
+ old_sess_out:
+- iscsi_stop_login_thread_timer(np);
+ /*
+ * If login negotiation fails check if the Time2Retain timer
+ * needs to be restarted.
+@@ -1440,8 +1439,9 @@ static int __iscsi_target_login_thread(s
+ new_sess_out:
+ new_sess = true;
+ old_sess_out:
++ iscsi_stop_login_thread_timer(np);
+ tpg_np = conn->tpg_np;
+- iscsi_target_login_sess_out(conn, np, zero_tsih, new_sess);
++ iscsi_target_login_sess_out(conn, zero_tsih, new_sess);
+ new_sess = false;
+
+ if (tpg) {
+--- a/drivers/target/iscsi/iscsi_target_login.h
++++ b/drivers/target/iscsi/iscsi_target_login.h
+@@ -22,8 +22,7 @@ extern int iscsit_put_login_tx(struct is
+ extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *);
+ extern int iscsit_start_kthreads(struct iscsi_conn *);
+ extern void iscsi_post_login_handler(struct iscsi_np *, struct iscsi_conn *, u8);
+-extern void iscsi_target_login_sess_out(struct iscsi_conn *, struct iscsi_np *,
+- bool, bool);
++extern void iscsi_target_login_sess_out(struct iscsi_conn *, bool, bool);
+ extern int iscsi_target_login_thread(void *);
+
+ #endif /*** ISCSI_TARGET_LOGIN_H ***/
+--- a/drivers/target/iscsi/iscsi_target_nego.c
++++ b/drivers/target/iscsi/iscsi_target_nego.c
+@@ -554,12 +554,11 @@ static bool iscsi_target_sk_check_and_cl
+
+ static void iscsi_target_login_drop(struct iscsi_conn *conn, struct iscsi_login *login)
+ {
+- struct iscsi_np *np = login->np;
+ bool zero_tsih = login->zero_tsih;
+
+ iscsi_remove_failed_auth_entry(conn);
+ iscsi_target_nego_release(conn);
+- iscsi_target_login_sess_out(conn, np, zero_tsih, true);
++ iscsi_target_login_sess_out(conn, zero_tsih, true);
+ }
+
+ static void iscsi_target_login_timeout(unsigned long data)
iio-accel-mma7455-fix-timestamp-alignment-and-prevent-data-leak.patch
iio-accel-mma8452-fix-timestamp-alignment-and-prevent-data-leak.patch
staging-wlan-ng-fix-out-of-bounds-read-in-prism2sta_probe_usb.patch
+btrfs-require-only-sector-size-alignment-for-parent-eb-bytenr.patch
+btrfs-fix-lockdep-splat-in-add_missing_dev.patch
+btrfs-fix-wrong-address-when-faulting-in-pages-in-the-search-ioctl.patch
+regulator-push-allocation-in-set_consumer_device_supply-out-of-lock.patch
+scsi-target-iscsi-fix-data-digest-calculation.patch
+scsi-target-iscsi-fix-hang-in-iscsit_access_np-when-getting-tpg-np_login_sem.patch