diff options
author | Pavel Shilovsky <pshilov@microsoft.com> | 2019-01-15 15:52:29 -0800 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2019-03-05 18:10:01 -0600 |
commit | 3349c3a79fb5d7632bfe426c014cbb589d1ca8e0 (patch) | |
tree | 21c3a55530782e36a9efb962abb67f73769b345d /fs/cifs/transport.c | |
parent | 34f4deb7c56c6fdc77a7e414203f0045bb6db32b (diff) | |
download | linux-3349c3a79fb5d7632bfe426c014cbb589d1ca8e0.tar.bz2 |
CIFS: Check for reconnects before sending async requests
The reconnect might have happended after we obtained credits
and before we acquired srv_mutex. Check for that under the mutex
and retry an async operation if the reconnect is detected.
Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/transport.c')
-rw-r--r-- | fs/cifs/transport.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 0ee36c3e66d3..5a3e499caec8 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -607,7 +607,8 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, mid_receive_t *receive, mid_callback_t *callback, - mid_handle_t *handle, void *cbdata, const int flags) + mid_handle_t *handle, void *cbdata, const int flags, + const struct cifs_credits *exist_credits) { int rc, timeout, optype; struct mid_q_entry *mid; @@ -623,9 +624,22 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, return rc; credits.value = 1; credits.instance = instance; - } + } else + instance = exist_credits->instance; mutex_lock(&server->srv_mutex); + + /* + * We can't use credits obtained from the previous session to send this + * request. Check if there were reconnects after we obtained credits and + * return -EAGAIN in such cases to let callers handle it. + */ + if (instance != server->reconnect_instance) { + mutex_unlock(&server->srv_mutex); + add_credits_and_wake_if(server, &credits, optype); + return -EAGAIN; + } + mid = server->ops->setup_async_request(server, rqst); if (IS_ERR(mid)) { mutex_unlock(&server->srv_mutex); |