--- /dev/null
+From 24d5373dda7c00a438d26016bce140299fae675e Mon Sep 17 00:00:00 2001
+From: Julien Grall <julien.grall@arm.com>
+Date: Wed, 7 Dec 2016 12:24:40 +0000
+Subject: arm/xen: Use alloc_percpu rather than __alloc_percpu
+
+From: Julien Grall <julien.grall@arm.com>
+
+commit 24d5373dda7c00a438d26016bce140299fae675e upstream.
+
+The function xen_guest_init is using __alloc_percpu with an alignment
+which are not power of two.
+
+However, the percpu allocator never supported alignments which are not power
+of two and has always behaved incorectly in thise case.
+
+Commit 3ca45a4 "percpu: ensure requested alignment is power of two"
+introduced a check which trigger a warning [1] when booting linux-next
+on Xen. But in reality this bug was always present.
+
+This can be fixed by replacing the call to __alloc_percpu with
+alloc_percpu. The latter will use an alignment which are a power of two.
+
+[1]
+
+[ 0.023921] illegal size (48) or align (48) for percpu allocation
+[ 0.024167] ------------[ cut here ]------------
+[ 0.024344] WARNING: CPU: 0 PID: 1 at linux/mm/percpu.c:892 pcpu_alloc+0x88/0x6c0
+[ 0.024584] Modules linked in:
+[ 0.024708]
+[ 0.024804] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
+4.9.0-rc7-next-20161128 #473
+[ 0.025012] Hardware name: Foundation-v8A (DT)
+[ 0.025162] task: ffff80003d870000 task.stack: ffff80003d844000
+[ 0.025351] PC is at pcpu_alloc+0x88/0x6c0
+[ 0.025490] LR is at pcpu_alloc+0x88/0x6c0
+[ 0.025624] pc : [<ffff00000818e678>] lr : [<ffff00000818e678>]
+pstate: 60000045
+[ 0.025830] sp : ffff80003d847cd0
+[ 0.025946] x29: ffff80003d847cd0 x28: 0000000000000000
+[ 0.026147] x27: 0000000000000000 x26: 0000000000000000
+[ 0.026348] x25: 0000000000000000 x24: 0000000000000000
+[ 0.026549] x23: 0000000000000000 x22: 00000000024000c0
+[ 0.026752] x21: ffff000008e97000 x20: 0000000000000000
+[ 0.026953] x19: 0000000000000030 x18: 0000000000000010
+[ 0.027155] x17: 0000000000000a3f x16: 00000000deadbeef
+[ 0.027357] x15: 0000000000000006 x14: ffff000088f79c3f
+[ 0.027573] x13: ffff000008f79c4d x12: 0000000000000041
+[ 0.027782] x11: 0000000000000006 x10: 0000000000000042
+[ 0.027995] x9 : ffff80003d847a40 x8 : 6f697461636f6c6c
+[ 0.028208] x7 : 6120757063726570 x6 : ffff000008f79c84
+[ 0.028419] x5 : 0000000000000005 x4 : 0000000000000000
+[ 0.028628] x3 : 0000000000000000 x2 : 000000000000017f
+[ 0.028840] x1 : ffff80003d870000 x0 : 0000000000000035
+[ 0.029056]
+[ 0.029152] ---[ end trace 0000000000000000 ]---
+[ 0.029297] Call trace:
+[ 0.029403] Exception stack(0xffff80003d847b00 to
+ 0xffff80003d847c30)
+[ 0.029621] 7b00: 0000000000000030 0001000000000000
+ffff80003d847cd0 ffff00000818e678
+[ 0.029901] 7b20: 0000000000000002 0000000000000004
+ffff000008f7c060 0000000000000035
+[ 0.030153] 7b40: ffff000008f79000 ffff000008c4cd88
+ffff80003d847bf0 ffff000008101778
+[ 0.030402] 7b60: 0000000000000030 0000000000000000
+ffff000008e97000 00000000024000c0
+[ 0.030647] 7b80: 0000000000000000 0000000000000000
+0000000000000000 0000000000000000
+[ 0.030895] 7ba0: 0000000000000035 ffff80003d870000
+000000000000017f 0000000000000000
+[ 0.031144] 7bc0: 0000000000000000 0000000000000005
+ffff000008f79c84 6120757063726570
+[ 0.031394] 7be0: 6f697461636f6c6c ffff80003d847a40
+0000000000000042 0000000000000006
+[ 0.031643] 7c00: 0000000000000041 ffff000008f79c4d
+ffff000088f79c3f 0000000000000006
+[ 0.031877] 7c20: 00000000deadbeef 0000000000000a3f
+[ 0.032051] [<ffff00000818e678>] pcpu_alloc+0x88/0x6c0
+[ 0.032229] [<ffff00000818ece8>] __alloc_percpu+0x18/0x20
+[ 0.032409] [<ffff000008d9606c>] xen_guest_init+0x174/0x2f4
+[ 0.032591] [<ffff0000080830f8>] do_one_initcall+0x38/0x130
+[ 0.032783] [<ffff000008d90c34>] kernel_init_freeable+0xe0/0x248
+[ 0.032995] [<ffff00000899a890>] kernel_init+0x10/0x100
+[ 0.033172] [<ffff000008082ec0>] ret_from_fork+0x10/0x50
+
+Reported-by: Wei Chen <wei.chen@arm.com>
+Link: https://lkml.org/lkml/2016/11/28/669
+Signed-off-by: Julien Grall <julien.grall@arm.com>
+Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
+Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/xen/enlighten.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -372,8 +372,7 @@ static int __init xen_guest_init(void)
+ * for secondary CPUs as they are brought up.
+ * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
+ */
+- xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
+- sizeof(struct vcpu_info));
++ xen_vcpu_info = alloc_percpu(struct vcpu_info);
+ if (xen_vcpu_info == NULL)
+ return -ENOMEM;
+
--- /dev/null
+From b0a752b5ce76bd1d8b733a53757c3263511dcb69 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Wed, 16 Nov 2016 15:17:15 -0800
+Subject: CIFS: Decrease verbosity of ioctl call
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit b0a752b5ce76bd1d8b733a53757c3263511dcb69 upstream.
+
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/ioctl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/ioctl.c
++++ b/fs/cifs/ioctl.c
+@@ -189,7 +189,7 @@ long cifs_ioctl(struct file *filep, unsi
+ xid = get_xid();
+
+ cifs_sb = CIFS_SB(inode->i_sb);
+- cifs_dbg(VFS, "cifs ioctl 0x%x\n", command);
++ cifs_dbg(FYI, "cifs ioctl 0x%x\n", command);
+ switch (command) {
+ case FS_IOC_GETFLAGS:
+ if (pSMBFile == NULL)
--- /dev/null
+From 96a988ffeb90dba33a71c3826086fe67c897a183 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 11:31:23 -0800
+Subject: CIFS: Fix a possible double locking of mutex during reconnect
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 96a988ffeb90dba33a71c3826086fe67c897a183 upstream.
+
+With the current code it is possible to lock a mutex twice when
+a subsequent reconnects are triggered. On the 1st reconnect we
+reconnect sessions and tcons and then persistent file handles.
+If the 2nd reconnect happens during the reconnecting of persistent
+file handles then the following sequence of calls is observed:
+
+cifs_reopen_file -> SMB2_open -> small_smb2_init -> smb2_reconnect
+-> cifs_reopen_persistent_file_handles -> cifs_reopen_file (again!).
+
+So, we are trying to acquire the same cfile->fh_mutex twice which
+is wrong. Fix this by moving reconnecting of persistent handles to
+the delayed work (smb2_reconnect_server) and submitting this work
+every time we reconnect tcon in SMB2 commands handling codepath.
+
+This can also lead to corruption of a temporary file list in
+cifs_reopen_persistent_file_handles() because we can recursively
+call this function twice.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h | 1 +
+ fs/cifs/file.c | 8 +++++++-
+ fs/cifs/smb2pdu.c | 14 +++++++++-----
+ fs/cifs/smb2pdu.h | 2 ++
+ 4 files changed, 19 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -925,6 +925,7 @@ struct cifs_tcon {
+ bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
+ bool broken_sparse_sup; /* if server or share does not support sparse */
+ bool need_reconnect:1; /* connection reset, tid now invalid */
++ bool need_reopen_files:1; /* need to reopen tcon file handles */
+ bool use_resilient:1; /* use resilient instead of durable handles */
+ bool use_persistent:1; /* use persistent instead of durable handles */
+ #ifdef CONFIG_CIFS_SMB2
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -777,6 +777,11 @@ cifs_reopen_persistent_handles(struct ci
+ struct list_head *tmp1;
+ struct list_head tmp_list;
+
++ if (!tcon->use_persistent || !tcon->need_reopen_files)
++ return;
++
++ tcon->need_reopen_files = false;
++
+ cifs_dbg(FYI, "Reopen persistent handles");
+ INIT_LIST_HEAD(&tmp_list);
+
+@@ -793,7 +798,8 @@ cifs_reopen_persistent_handles(struct ci
+
+ list_for_each_safe(tmp, tmp1, &tmp_list) {
+ open_file = list_entry(tmp, struct cifsFileInfo, rlist);
+- cifs_reopen_file(open_file, false /* do not flush */);
++ if (cifs_reopen_file(open_file, false /* do not flush */))
++ tcon->need_reopen_files = true;
+ list_del_init(&open_file->rlist);
+ cifsFileInfo_put(open_file);
+ }
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -250,16 +250,19 @@ smb2_reconnect(__le16 smb2_command, stru
+ }
+
+ cifs_mark_open_files_invalid(tcon);
++ if (tcon->use_persistent)
++ tcon->need_reopen_files = true;
+
+ rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage);
+ mutex_unlock(&tcon->ses->session_mutex);
+
+- if (tcon->use_persistent)
+- cifs_reopen_persistent_handles(tcon);
+-
+ cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
+ if (rc)
+ goto out;
++
++ if (smb2_command != SMB2_INTERNAL_CMD)
++ queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++
+ atomic_inc(&tconInfoReconnectCount);
+ out:
+ /*
+@@ -1990,7 +1993,7 @@ void smb2_reconnect_server(struct work_s
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
+- if (tcon->need_reconnect) {
++ if (tcon->need_reconnect || tcon->need_reopen_files) {
+ tcon->tc_count++;
+ list_add_tail(&tcon->rlist, &tmp_list);
+ tcon_exist = true;
+@@ -2007,7 +2010,8 @@ void smb2_reconnect_server(struct work_s
+ spin_unlock(&cifs_tcp_ses_lock);
+
+ list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
+- smb2_reconnect(SMB2_ECHO, tcon);
++ if (!smb2_reconnect(SMB2_INTERNAL_CMD, tcon))
++ cifs_reopen_persistent_handles(tcon);
+ list_del_init(&tcon->rlist);
+ cifs_put_tcon(tcon);
+ }
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -80,6 +80,8 @@
+ #define SMB2_SET_INFO cpu_to_le16(SMB2_SET_INFO_HE)
+ #define SMB2_OPLOCK_BREAK cpu_to_le16(SMB2_OPLOCK_BREAK_HE)
+
++#define SMB2_INTERNAL_CMD cpu_to_le16(0xFFFF)
++
+ #define NUMBER_OF_SMB2_COMMANDS 0x0013
+
+ /* BB FIXME - analyze following length BB */
--- /dev/null
+From 53e0e11efe9289535b060a51d4cf37c25e0d0f2b Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Fri, 4 Nov 2016 11:50:31 -0700
+Subject: CIFS: Fix a possible memory corruption during reconnect
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 53e0e11efe9289535b060a51d4cf37c25e0d0f2b upstream.
+
+We can not unlock/lock cifs_tcp_ses_lock while walking through ses
+and tcon lists because it can corrupt list iterator pointers and
+a tcon structure can be released if we don't hold an extra reference.
+Fix it by moving a reconnect process to a separate delayed work
+and acquiring a reference to every tcon that needs to be reconnected.
+Also do not send an echo request on newly established connections.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h | 3 ++
+ fs/cifs/cifsproto.h | 3 ++
+ fs/cifs/connect.c | 34 ++++++++++++++++++-----
+ fs/cifs/smb2pdu.c | 75 +++++++++++++++++++++++++++++++++++-----------------
+ fs/cifs/smb2proto.h | 1
+ 5 files changed, 85 insertions(+), 31 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -646,6 +646,8 @@ struct TCP_Server_Info {
+ unsigned int max_read;
+ unsigned int max_write;
+ __u8 preauth_hash[512];
++ struct delayed_work reconnect; /* reconnect workqueue job */
++ struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
+ #endif /* CONFIG_CIFS_SMB2 */
+ unsigned long echo_interval;
+ };
+@@ -849,6 +851,7 @@ cap_unix(struct cifs_ses *ses)
+ struct cifs_tcon {
+ struct list_head tcon_list;
+ int tc_count;
++ struct list_head rlist; /* reconnect list */
+ struct list_head openFileList;
+ spinlock_t open_file_lock; /* protects list above */
+ struct cifs_ses *ses; /* pointer to session associated with */
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -206,6 +206,9 @@ extern void cifs_add_pending_open_locked
+ struct tcon_link *tlink,
+ struct cifs_pending_open *open);
+ extern void cifs_del_pending_open(struct cifs_pending_open *open);
++extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
++ int from_reconnect);
++extern void cifs_put_tcon(struct cifs_tcon *tcon);
+
+ #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
+ extern void cifs_dfs_release_automount_timer(void);
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -52,6 +52,9 @@
+ #include "nterr.h"
+ #include "rfc1002pdu.h"
+ #include "fscache.h"
++#ifdef CONFIG_CIFS_SMB2
++#include "smb2proto.h"
++#endif
+
+ #define CIFS_PORT 445
+ #define RFC1001_PORT 139
+@@ -2100,8 +2103,8 @@ cifs_find_tcp_session(struct smb_vol *vo
+ return NULL;
+ }
+
+-static void
+-cifs_put_tcp_session(struct TCP_Server_Info *server)
++void
++cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ {
+ struct task_struct *task;
+
+@@ -2118,6 +2121,19 @@ cifs_put_tcp_session(struct TCP_Server_I
+
+ cancel_delayed_work_sync(&server->echo);
+
++#ifdef CONFIG_CIFS_SMB2
++ if (from_reconnect)
++ /*
++ * Avoid deadlock here: reconnect work calls
++ * cifs_put_tcp_session() at its end. Need to be sure
++ * that reconnect work does nothing with server pointer after
++ * that step.
++ */
++ cancel_delayed_work(&server->reconnect);
++ else
++ cancel_delayed_work_sync(&server->reconnect);
++#endif
++
+ spin_lock(&GlobalMid_Lock);
+ server->tcpStatus = CifsExiting;
+ spin_unlock(&GlobalMid_Lock);
+@@ -2182,6 +2198,10 @@ cifs_get_tcp_session(struct smb_vol *vol
+ INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
+ INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+ INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
++#ifdef CONFIG_CIFS_SMB2
++ INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
++ mutex_init(&tcp_ses->reconnect_mutex);
++#endif
+ memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
+ sizeof(tcp_ses->srcaddr));
+ memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
+@@ -2340,7 +2360,7 @@ cifs_put_smb_ses(struct cifs_ses *ses)
+ spin_unlock(&cifs_tcp_ses_lock);
+
+ sesInfoFree(ses);
+- cifs_put_tcp_session(server);
++ cifs_put_tcp_session(server, 0);
+ }
+
+ #ifdef CONFIG_KEYS
+@@ -2514,7 +2534,7 @@ cifs_get_smb_ses(struct TCP_Server_Info
+ mutex_unlock(&ses->session_mutex);
+
+ /* existing SMB ses has a server reference already */
+- cifs_put_tcp_session(server);
++ cifs_put_tcp_session(server, 0);
+ free_xid(xid);
+ return ses;
+ }
+@@ -2604,7 +2624,7 @@ cifs_find_tcon(struct cifs_ses *ses, con
+ return NULL;
+ }
+
+-static void
++void
+ cifs_put_tcon(struct cifs_tcon *tcon)
+ {
+ unsigned int xid;
+@@ -3792,7 +3812,7 @@ mount_fail_check:
+ else if (ses)
+ cifs_put_smb_ses(ses);
+ else
+- cifs_put_tcp_session(server);
++ cifs_put_tcp_session(server, 0);
+ bdi_destroy(&cifs_sb->bdi);
+ }
+
+@@ -4103,7 +4123,7 @@ cifs_construct_tcon(struct cifs_sb_info
+ ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
+ if (IS_ERR(ses)) {
+ tcon = (struct cifs_tcon *)ses;
+- cifs_put_tcp_session(master_tcon->ses->server);
++ cifs_put_tcp_session(master_tcon->ses->server, 0);
+ goto out;
+ }
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1972,6 +1972,54 @@ smb2_echo_callback(struct mid_q_entry *m
+ add_credits(server, credits_received, CIFS_ECHO_OP);
+ }
+
++void smb2_reconnect_server(struct work_struct *work)
++{
++ struct TCP_Server_Info *server = container_of(work,
++ struct TCP_Server_Info, reconnect.work);
++ struct cifs_ses *ses;
++ struct cifs_tcon *tcon, *tcon2;
++ struct list_head tmp_list;
++ int tcon_exist = false;
++
++ /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
++ mutex_lock(&server->reconnect_mutex);
++
++ INIT_LIST_HEAD(&tmp_list);
++ cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
++
++ spin_lock(&cifs_tcp_ses_lock);
++ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
++ if (tcon->need_reconnect) {
++ tcon->tc_count++;
++ list_add_tail(&tcon->rlist, &tmp_list);
++ tcon_exist = true;
++ }
++ }
++ }
++ /*
++ * Get the reference to server struct to be sure that the last call of
++ * cifs_put_tcon() in the loop below won't release the server pointer.
++ */
++ if (tcon_exist)
++ server->srv_count++;
++
++ spin_unlock(&cifs_tcp_ses_lock);
++
++ list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
++ smb2_reconnect(SMB2_ECHO, tcon);
++ list_del_init(&tcon->rlist);
++ cifs_put_tcon(tcon);
++ }
++
++ cifs_dbg(FYI, "Reconnecting tcons finished\n");
++ mutex_unlock(&server->reconnect_mutex);
++
++ /* now we can safely release srv struct */
++ if (tcon_exist)
++ cifs_put_tcp_session(server, 1);
++}
++
+ int
+ SMB2_echo(struct TCP_Server_Info *server)
+ {
+@@ -1984,32 +2032,11 @@ SMB2_echo(struct TCP_Server_Info *server
+ cifs_dbg(FYI, "In echo request\n");
+
+ if (server->tcpStatus == CifsNeedNegotiate) {
+- struct list_head *tmp, *tmp2;
+- struct cifs_ses *ses;
+- struct cifs_tcon *tcon;
+-
+- cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+- spin_lock(&cifs_tcp_ses_lock);
+- list_for_each(tmp, &server->smb_ses_list) {
+- ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+- list_for_each(tmp2, &ses->tcon_list) {
+- tcon = list_entry(tmp2, struct cifs_tcon,
+- tcon_list);
+- /* add check for persistent handle reconnect */
+- if (tcon && tcon->need_reconnect) {
+- spin_unlock(&cifs_tcp_ses_lock);
+- rc = smb2_reconnect(SMB2_ECHO, tcon);
+- spin_lock(&cifs_tcp_ses_lock);
+- }
+- }
+- }
+- spin_unlock(&cifs_tcp_ses_lock);
++ /* No need to send echo on newly established connections */
++ queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++ return rc;
+ }
+
+- /* if no session, renegotiate failed above */
+- if (server->tcpStatus == CifsNeedNegotiate)
+- return -EIO;
+-
+ rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
+ if (rc)
+ return rc;
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+ struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
++extern void smb2_reconnect_server(struct work_struct *work);
+
+ /*
+ * SMB2 Worker functions - most of protocol specific implementation details
--- /dev/null
+From e3d240e9d505fc67f8f8735836df97a794bbd946 Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 16:14:43 -0800
+Subject: CIFS: Fix a possible memory corruption in push locks
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit e3d240e9d505fc67f8f8735836df97a794bbd946 upstream.
+
+If maxBuf is not 0 but less than a size of SMB2 lock structure
+we can end up with a memory corruption.
+
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -260,7 +260,7 @@ smb2_push_mandatory_locks(struct cifsFil
+ * and check it for zero before using.
+ */
+ max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
+- if (!max_buf) {
++ if (max_buf < sizeof(struct smb2_lock_element)) {
+ free_xid(xid);
+ return -EINVAL;
+ }
--- /dev/null
+From 4772c79599564bd08ee6682715a7d3516f67433f Mon Sep 17 00:00:00 2001
+From: Pavel Shilovsky <pshilov@microsoft.com>
+Date: Tue, 29 Nov 2016 11:30:58 -0800
+Subject: CIFS: Fix missing nls unload in smb2_reconnect()
+
+From: Pavel Shilovsky <pshilov@microsoft.com>
+
+commit 4772c79599564bd08ee6682715a7d3516f67433f upstream.
+
+Acked-by: Sachin Prabhu <sprabhu@redhat.com>
+Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb2pdu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -280,7 +280,7 @@ out:
+ case SMB2_CHANGE_NOTIFY:
+ case SMB2_QUERY_INFO:
+ case SMB2_SET_INFO:
+- return -EAGAIN;
++ rc = -EAGAIN;
+ }
+ unload_nls(nls_codepage);
+ return rc;
--- /dev/null
+From 06deeec77a5a689cc94b21a8a91a76e42176685d Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Mon, 12 Dec 2016 12:54:37 -0800
+Subject: cifs: Fix smbencrypt() to stop pointing a scatterlist at the stack
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit 06deeec77a5a689cc94b21a8a91a76e42176685d upstream.
+
+smbencrypt() points a scatterlist to the stack, which is breaks if
+CONFIG_VMAP_STACK=y.
+
+Fix it by switching to crypto_cipher_encrypt_one(). The new code
+should be considerably faster as an added benefit.
+
+This code is nearly identical to some code that Eric Biggers
+suggested.
+
+Reported-by: Eric Biggers <ebiggers3@gmail.com>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Acked-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smbencrypt.c | 40 ++++++++--------------------------------
+ 1 file changed, 8 insertions(+), 32 deletions(-)
+
+--- a/fs/cifs/smbencrypt.c
++++ b/fs/cifs/smbencrypt.c
+@@ -23,7 +23,7 @@
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+-#include <crypto/skcipher.h>
++#include <linux/crypto.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/fs.h>
+@@ -69,46 +69,22 @@ str_to_key(unsigned char *str, unsigned
+ static int
+ smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
+ {
+- int rc;
+ unsigned char key2[8];
+- struct crypto_skcipher *tfm_des;
+- struct scatterlist sgin, sgout;
+- struct skcipher_request *req;
++ struct crypto_cipher *tfm_des;
+
+ str_to_key(key, key2);
+
+- tfm_des = crypto_alloc_skcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
++ tfm_des = crypto_alloc_cipher("des", 0, 0);
+ if (IS_ERR(tfm_des)) {
+- rc = PTR_ERR(tfm_des);
+ cifs_dbg(VFS, "could not allocate des crypto API\n");
+- goto smbhash_err;
++ return PTR_ERR(tfm_des);
+ }
+
+- req = skcipher_request_alloc(tfm_des, GFP_KERNEL);
+- if (!req) {
+- rc = -ENOMEM;
+- cifs_dbg(VFS, "could not allocate des crypto API\n");
+- goto smbhash_free_skcipher;
+- }
+-
+- crypto_skcipher_setkey(tfm_des, key2, 8);
+-
+- sg_init_one(&sgin, in, 8);
+- sg_init_one(&sgout, out, 8);
+-
+- skcipher_request_set_callback(req, 0, NULL, NULL);
+- skcipher_request_set_crypt(req, &sgin, &sgout, 8, NULL);
+-
+- rc = crypto_skcipher_encrypt(req);
+- if (rc)
+- cifs_dbg(VFS, "could not encrypt crypt key rc: %d\n", rc);
+-
+- skcipher_request_free(req);
++ crypto_cipher_setkey(tfm_des, key2, 8);
++ crypto_cipher_encrypt_one(tfm_des, out, in);
++ crypto_free_cipher(tfm_des);
+
+-smbhash_free_skcipher:
+- crypto_free_skcipher(tfm_des);
+-smbhash_err:
+- return rc;
++ return 0;
+ }
+
+ static int
--- /dev/null
+From 2d13bb6494c807bcf3f78af0e96c0b8615a94385 Mon Sep 17 00:00:00 2001
+From: Douglas Anderson <dianders@chromium.org>
+Date: Wed, 14 Dec 2016 15:05:49 -0800
+Subject: kernel/debug/debug_core.c: more properly delay for secondary CPUs
+
+From: Douglas Anderson <dianders@chromium.org>
+
+commit 2d13bb6494c807bcf3f78af0e96c0b8615a94385 upstream.
+
+We've got a delay loop waiting for secondary CPUs. That loop uses
+loops_per_jiffy. However, loops_per_jiffy doesn't actually mean how
+many tight loops make up a jiffy on all architectures. It is quite
+common to see things like this in the boot log:
+
+ Calibrating delay loop (skipped), value calculated using timer
+ frequency.. 48.00 BogoMIPS (lpj=24000)
+
+In my case I was seeing lots of cases where other CPUs timed out
+entering the debugger only to print their stack crawls shortly after the
+kdb> prompt was written.
+
+Elsewhere in kgdb we already use udelay(), so that should be safe enough
+to use to implement our timeout. We'll delay 1 ms for 1000 times, which
+should give us a full second of delay (just like the old code wanted)
+but allow us to notice that we're done every 1 ms.
+
+[akpm@linux-foundation.org: simplifications, per Daniel]
+Link: http://lkml.kernel.org/r/1477091361-2039-1-git-send-email-dianders@chromium.org
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
+Cc: Jason Wessel <jason.wessel@windriver.com>
+Cc: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/debug/debug_core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/debug/debug_core.c
++++ b/kernel/debug/debug_core.c
+@@ -598,11 +598,11 @@ return_normal:
+ /*
+ * Wait for the other CPUs to be notified and be waiting for us:
+ */
+- time_left = loops_per_jiffy * HZ;
++ time_left = MSEC_PER_SEC;
+ while (kgdb_do_roundup && --time_left &&
+ (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
+ online_cpus)
+- cpu_relax();
++ udelay(1000);
+ if (!time_left)
+ pr_crit("Timed out waiting for secondary CPUs.\n");
+
--- /dev/null
+From 4d1f0fb096aedea7bb5489af93498a82e467c480 Mon Sep 17 00:00:00 2001
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Date: Wed, 14 Dec 2016 15:04:04 -0800
+Subject: kernel/watchdog: use nmi registers snapshot in hardlockup handler
+
+From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+
+commit 4d1f0fb096aedea7bb5489af93498a82e467c480 upstream.
+
+NMI handler doesn't call set_irq_regs(), it's set only by normal IRQ.
+Thus get_irq_regs() returns NULL or stale registers snapshot with IP/SP
+pointing to the code interrupted by IRQ which was interrupted by NMI.
+NULL isn't a problem: in this case watchdog calls dump_stack() and
+prints full stack trace including NMI. But if we're stuck in IRQ
+handler then NMI watchlog will print stack trace without IRQ part at
+all.
+
+This patch uses registers snapshot passed into NMI handler as arguments:
+these registers point exactly to the instruction interrupted by NMI.
+
+Fixes: 55537871ef66 ("kernel/watchdog.c: perform all-CPU backtrace in case of hard lockup")
+Link: http://lkml.kernel.org/r/146771764784.86724.6006627197118544150.stgit@buzz
+Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Cc: Jiri Kosina <jkosina@suse.cz>
+Cc: Ulrich Obergfell <uobergfe@redhat.com>
+Cc: Aaron Tomlin <atomlin@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/watchdog.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -344,7 +344,6 @@ static void watchdog_overflow_callback(s
+ */
+ if (is_hardlockup()) {
+ int this_cpu = smp_processor_id();
+- struct pt_regs *regs = get_irq_regs();
+
+ /* only print hardlockups once */
+ if (__this_cpu_read(hard_watchdog_warn) == true)
dm-raid-fix-discard-support-regression.patch
dm-space-map-metadata-fix-struct-sm_metadata-leak-on-failed-create.patch
asoc-intel-fix-crash-at-suspend-resume-without-card-registration.patch
+cifs-fix-smbencrypt-to-stop-pointing-a-scatterlist-at-the-stack.patch
+cifs-fix-a-possible-memory-corruption-during-reconnect.patch
+cifs-fix-missing-nls-unload-in-smb2_reconnect.patch
+cifs-fix-a-possible-double-locking-of-mutex-during-reconnect.patch
+cifs-decrease-verbosity-of-ioctl-call.patch
+cifs-fix-a-possible-memory-corruption-in-push-locks.patch
+kernel-watchdog-use-nmi-registers-snapshot-in-hardlockup-handler.patch
+watchdog-mei_wdt-request-stop-on-reboot-to-prevent-false-positive-event.patch
+watchdog-qcom-fix-kernel-panic-due-to-external-abort-on-non-linefetch.patch
+kernel-debug-debug_core.c-more-properly-delay-for-secondary-cpus.patch
+tpm-xen-remove-bogus-tpm_chip_unregister.patch
+xen-gntdev-use-vm_mixedmap-instead-of-vm_io-to-avoid-numa-balancing.patch
+arm-xen-use-alloc_percpu-rather-than-__alloc_percpu.patch
+xfs-fix-up-xfs_swap_extent_forks-inline-extent-handling.patch
+xfs-set-agi-buffer-type-in-xlog_recover_clear_agi_bucket.patch
--- /dev/null
+From 1f0f30e404b3d8f4597a2d9b77fba55452f8fd0e Mon Sep 17 00:00:00 2001
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+Date: Wed, 26 Oct 2016 16:28:45 -0600
+Subject: tpm xen: Remove bogus tpm_chip_unregister
+
+From: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+
+commit 1f0f30e404b3d8f4597a2d9b77fba55452f8fd0e upstream.
+
+tpm_chip_unregister can only be called after tpm_chip_register.
+devm manages the allocation so no unwind is needed here.
+
+Fixes: afb5abc262e96 ("tpm: two-phase chip management functions")
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/xen-tpmfront.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/char/tpm/xen-tpmfront.c
++++ b/drivers/char/tpm/xen-tpmfront.c
+@@ -307,7 +307,6 @@ static int tpmfront_probe(struct xenbus_
+ rv = setup_ring(dev, priv);
+ if (rv) {
+ chip = dev_get_drvdata(&dev->dev);
+- tpm_chip_unregister(chip);
+ ring_free(priv);
+ return rv;
+ }
--- /dev/null
+From 9eff1140a82db8c5520f76e51c21827b4af670b3 Mon Sep 17 00:00:00 2001
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+Date: Tue, 8 Nov 2016 17:55:52 +0200
+Subject: watchdog: mei_wdt: request stop on reboot to prevent false positive event
+
+From: Alexander Usyskin <alexander.usyskin@intel.com>
+
+commit 9eff1140a82db8c5520f76e51c21827b4af670b3 upstream.
+
+Systemd on reboot enables shutdown watchdog that leaves the watchdog
+device open to ensure that even if power down process get stuck the
+platform reboots nonetheless.
+The iamt_wdt is an alarm-only watchdog and can't reboot system, but the
+FW will generate an alarm event reboot was completed in time, as the
+watchdog is not automatically disabled during power cycle.
+So we should request stop watchdog on reboot to eliminate wrong alarm
+from the FW.
+
+Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
+Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/mei_wdt.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/watchdog/mei_wdt.c
++++ b/drivers/watchdog/mei_wdt.c
+@@ -389,6 +389,8 @@ static int mei_wdt_register(struct mei_w
+ wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
+
+ watchdog_set_drvdata(&wdt->wdd, wdt);
++ watchdog_stop_on_reboot(&wdt->wdd);
++
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret) {
+ dev_err(dev, "unable to register watchdog device = %d.\n", ret);
--- /dev/null
+From f06f35c66fdbd5ac38901a3305ce763a0cd59375 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Mon, 14 Nov 2016 02:11:16 +0100
+Subject: watchdog: qcom: fix kernel panic due to external abort on non-linefetch
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit f06f35c66fdbd5ac38901a3305ce763a0cd59375 upstream.
+
+This patch fixes a off-by-one in the "watchdog: qcom: add option for
+standalone watchdog not in timer block" patch that causes the
+following panic on boot:
+
+> Unhandled fault: external abort on non-linefetch (0x1008) at 0xc8874002
+> pgd = c0204000
+> [c8874002] *pgd=87806811, *pte=0b017653, *ppte=0b017453
+> Internal error: : 1008 [#1] SMP ARM
+> CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.8.6 #0
+> Hardware name: Generic DT based system
+> PC is at 0xc02222f4
+> LR is at 0x1
+> pc : [<c02222f4>] lr : [<00000001>] psr: 00000113
+> sp : c782fc98 ip : 00000003 fp : 00000000
+> r10: 00000004 r9 : c782e000 r8 : c04ab98c
+> r7 : 00000001 r6 : c8874002 r5 : c782fe00 r4 : 00000002
+> r3 : 00000000 r2 : c782fe00 r1 : 00100000 r0 : c8874002
+> Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
+> Control: 10c5387d Table: 8020406a DAC: 00000051
+> Process swapper/0 (pid: 1, stack limit = 0xc782e210)
+> Stack: (0xc782fc98 to 0xc7830000)
+> [...]
+
+The WDT_STS (status) needs to be translated via wdt_addr as well.
+
+fixes: f0d9d0f4b44a ("watchdog: qcom: add option for standalone watchdog not in timer block")
+Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
+Reviewed-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/watchdog/qcom-wdt.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/watchdog/qcom-wdt.c
++++ b/drivers/watchdog/qcom-wdt.c
+@@ -209,7 +209,7 @@ static int qcom_wdt_probe(struct platfor
+ wdt->wdd.parent = &pdev->dev;
+ wdt->layout = regs;
+
+- if (readl(wdt->base + WDT_STS) & 1)
++ if (readl(wdt_addr(wdt, WDT_STS)) & 1)
+ wdt->wdd.bootstatus = WDIOF_CARDRESET;
+
+ /*
--- /dev/null
+From 30faaafdfa0c754c91bac60f216c9f34a2bfdf7e Mon Sep 17 00:00:00 2001
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Date: Mon, 21 Nov 2016 09:56:06 -0500
+Subject: xen/gntdev: Use VM_MIXEDMAP instead of VM_IO to avoid NUMA balancing
+
+From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+
+commit 30faaafdfa0c754c91bac60f216c9f34a2bfdf7e upstream.
+
+Commit 9c17d96500f7 ("xen/gntdev: Grant maps should not be subject to
+NUMA balancing") set VM_IO flag to prevent grant maps from being
+subjected to NUMA balancing.
+
+It was discovered recently that this flag causes get_user_pages() to
+always fail with -EFAULT.
+
+check_vma_flags
+__get_user_pages
+__get_user_pages_locked
+__get_user_pages_unlocked
+get_user_pages_fast
+iov_iter_get_pages
+dio_refill_pages
+do_direct_IO
+do_blockdev_direct_IO
+do_blockdev_direct_IO
+ext4_direct_IO_read
+generic_file_read_iter
+aio_run_iocb
+
+(which can happen if guest's vdisk has direct-io-safe option).
+
+To avoid this let's use VM_MIXEDMAP flag instead --- it prevents
+NUMA balancing just as VM_IO does and has no effect on
+check_vma_flags().
+
+
+Reported-by: Olaf Hering <olaf@aepfle.de>
+Suggested-by: Hugh Dickins <hughd@google.com>
+Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Tested-by: Olaf Hering <olaf@aepfle.de>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/gntdev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -1007,7 +1007,7 @@ static int gntdev_mmap(struct file *flip
+
+ vma->vm_ops = &gntdev_vmops;
+
+- vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
++ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP;
+
+ if (use_ptemod)
+ vma->vm_flags |= VM_DONTCOPY;
--- /dev/null
+From 4dfce57db6354603641132fac3c887614e3ebe81 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Tue, 8 Nov 2016 12:55:18 +1100
+Subject: xfs: fix up xfs_swap_extent_forks inline extent handling
+
+From: Eric Sandeen <sandeen@sandeen.net>
+
+commit 4dfce57db6354603641132fac3c887614e3ebe81 upstream.
+
+There have been several reports over the years of NULL pointer
+dereferences in xfs_trans_log_inode during xfs_fsr processes,
+when the process is doing an fput and tearing down extents
+on the temporary inode, something like:
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
+PID: 29439 TASK: ffff880550584fa0 CPU: 6 COMMAND: "xfs_fsr"
+ [exception RIP: xfs_trans_log_inode+0x10]
+ #9 [ffff8800a57bbbe0] xfs_bunmapi at ffffffffa037398e [xfs]
+#10 [ffff8800a57bbce8] xfs_itruncate_extents at ffffffffa0391b29 [xfs]
+#11 [ffff8800a57bbd88] xfs_inactive_truncate at ffffffffa0391d0c [xfs]
+#12 [ffff8800a57bbdb8] xfs_inactive at ffffffffa0392508 [xfs]
+#13 [ffff8800a57bbdd8] xfs_fs_evict_inode at ffffffffa035907e [xfs]
+#14 [ffff8800a57bbe00] evict at ffffffff811e1b67
+#15 [ffff8800a57bbe28] iput at ffffffff811e23a5
+#16 [ffff8800a57bbe58] dentry_kill at ffffffff811dcfc8
+#17 [ffff8800a57bbe88] dput at ffffffff811dd06c
+#18 [ffff8800a57bbea8] __fput at ffffffff811c823b
+#19 [ffff8800a57bbef0] ____fput at ffffffff811c846e
+#20 [ffff8800a57bbf00] task_work_run at ffffffff81093b27
+#21 [ffff8800a57bbf30] do_notify_resume at ffffffff81013b0c
+#22 [ffff8800a57bbf50] int_signal at ffffffff8161405d
+
+As it turns out, this is because the i_itemp pointer, along
+with the d_ops pointer, has been overwritten with zeros
+when we tear down the extents during truncate. When the in-core
+inode fork on the temporary inode used by xfs_fsr was originally
+set up during the extent swap, we mistakenly looked at di_nextents
+to determine whether all extents fit inline, but this misses extents
+generated by speculative preallocation; we should be using if_bytes
+instead.
+
+This mistake corrupts the in-memory inode, and code in
+xfs_iext_remove_inline eventually gets bad inputs, causing
+it to memmove and memset incorrect ranges; this became apparent
+because the two values in ifp->if_u2.if_inline_ext[1] contained
+what should have been in d_ops and i_itemp; they were memmoved due
+to incorrect array indexing and then the original locations
+were zeroed with memset, again due to an array overrun.
+
+Fix this by properly using i_df.if_bytes to determine the number
+of extents, not di_nextents.
+
+Thanks to dchinner for looking at this with me and spotting the
+root cause.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_bmap_util.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_bmap_util.c
++++ b/fs/xfs/xfs_bmap_util.c
+@@ -1792,6 +1792,7 @@ xfs_swap_extent_forks(
+ struct xfs_ifork tempifp, *ifp, *tifp;
+ int aforkblks = 0;
+ int taforkblks = 0;
++ xfs_extnum_t nextents;
+ __uint64_t tmp;
+ int error;
+
+@@ -1881,7 +1882,8 @@ xfs_swap_extent_forks(
+ * pointer. Otherwise it's already NULL or
+ * pointing to the extent.
+ */
+- if (ip->i_d.di_nextents <= XFS_INLINE_EXTS) {
++ nextents = ip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
++ if (nextents <= XFS_INLINE_EXTS) {
+ ifp->if_u1.if_extents =
+ ifp->if_u2.if_inline_ext;
+ }
+@@ -1900,7 +1902,8 @@ xfs_swap_extent_forks(
+ * pointer. Otherwise it's already NULL or
+ * pointing to the extent.
+ */
+- if (tip->i_d.di_nextents <= XFS_INLINE_EXTS) {
++ nextents = tip->i_df.if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
++ if (nextents <= XFS_INLINE_EXTS) {
+ tifp->if_u1.if_extents =
+ tifp->if_u2.if_inline_ext;
+ }
--- /dev/null
+From 6b10b23ca94451fae153a5cc8d62fd721bec2019 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@sandeen.net>
+Date: Mon, 5 Dec 2016 12:31:06 +1100
+Subject: xfs: set AGI buffer type in xlog_recover_clear_agi_bucket
+
+From: Eric Sandeen <sandeen@sandeen.net>
+
+commit 6b10b23ca94451fae153a5cc8d62fd721bec2019 upstream.
+
+xlog_recover_clear_agi_bucket didn't set the
+type to XFS_BLFT_AGI_BUF, so we got a warning during log
+replay (or an ASSERT on a debug build).
+
+ XFS (md0): Unknown buffer type 0!
+ XFS (md0): _xfs_buf_ioapply: no ops on block 0xaea8802/0x1
+
+Fix this, as was done in f19b872b for 2 other locations
+with the same problem.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_log_recover.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -4929,6 +4929,7 @@ xlog_recover_clear_agi_bucket(
+ agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+ offset = offsetof(xfs_agi_t, agi_unlinked) +
+ (sizeof(xfs_agino_t) * bucket);
++ xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
+ xfs_trans_log_buf(tp, agibp, offset,
+ (offset + sizeof(xfs_agino_t) - 1));
+