summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilov@microsoft.com>2019-01-17 08:21:24 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-01-31 08:13:44 +0100
commit8a9c970fabb704846e527fdd4eeca0cab3a91137 (patch)
tree94d981df283c4d17c6c5f11b2e1b6897f484f47b /fs
parentbe0cb9e226b7c594070eb64ef8c18f3793f63976 (diff)
downloadlinux-stable-8a9c970fabb704846e527fdd4eeca0cab3a91137.tar.gz
linux-stable-8a9c970fabb704846e527fdd4eeca0cab3a91137.tar.bz2
linux-stable-8a9c970fabb704846e527fdd4eeca0cab3a91137.zip
CIFS: Fix possible hang during async MTU reads and writes
commit acc58d0bab55a50e02c25f00bd6a210ee121595f upstream. When doing MTU i/o we need to leave some credits for possible reopen requests and other operations happening in parallel. Currently we leave 1 credit which is not enough even for reopen only: we need at least 2 credits if durable handle reconnect fails. Also there may be other operations at the same time including compounding ones which require 3 credits at a time each. Fix this by leaving 8 credits which is big enough to cover most scenarios. Was able to reproduce this when server was configured to give out fewer credits than usual. The proper fix would be to reconnect a file handle first and then obtain credits for an MTU request but this leads to bigger code changes and should happen in other patches. Cc: <stable@vger.kernel.org> Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/smb2ops.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 3372eedaa94d..d4360404c62b 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -153,14 +153,14 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
scredits = server->credits;
/* can deadlock with reopen */
- if (scredits == 1) {
+ if (scredits <= 8) {
*num = SMB2_MAX_BUFFER_SIZE;
*credits = 0;
break;
}
- /* leave one credit for a possible reopen */
- scredits--;
+ /* leave some credits for reopen and other ops */
+ scredits -= 8;
*num = min_t(unsigned int, size,
scredits * SMB2_MAX_BUFFER_SIZE);