--- /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
+@@ -2129,7 +2129,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 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
+@@ -1139,7 +1139,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;
+@@ -1161,7 +1161,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.
+@@ -1407,8 +1406,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
+@@ -14,8 +14,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
+@@ -547,12 +547,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)