summaryrefslogtreecommitdiff
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilov@microsoft.com>2019-01-25 11:59:01 -0800
committerSteve French <stfrench@microsoft.com>2019-03-05 18:10:01 -0600
commit3e9529944d4177bd3a0952f4e7fe4f76c0f9bf6f (patch)
treedb847ea4a4550c488b785175edd4f0f0c74546d5 /fs/cifs/file.c
parentf0b93cb9d10789381c2c8c3bcab2315c3dcb3311 (diff)
CIFS: Reopen file before get SMB2 MTU credits for async IO
Currently we get MTU credits before we check an open file if it needs to be reopened. Reopening the file in such conditions leads to a possibility of being stuck waiting indefinitely for credits in the transport layer. Fix this by reopening the file first if needed and then getting MTU credits for async IO. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 67b361afb076..eaf5acba7f6b 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2650,6 +2650,14 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
struct cifs_credits credits_on_stack;
struct cifs_credits *credits = &credits_on_stack;
+ if (open_file->invalidHandle) {
+ rc = cifs_reopen_file(open_file, false);
+ if (rc == -EAGAIN)
+ continue;
+ else if (rc)
+ break;
+ }
+
rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
&wsize, credits);
if (rc)
@@ -2751,9 +2759,8 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
if (!rc) {
if (wdata->cfile->invalidHandle)
- rc = cifs_reopen_file(wdata->cfile, false);
-
- if (!rc)
+ rc = -EAGAIN;
+ else
rc = server->ops->async_writev(wdata,
cifs_uncached_writedata_release);
}
@@ -3355,6 +3362,14 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
iov_iter_advance(&direct_iov, offset - ctx->pos);
do {
+ if (open_file->invalidHandle) {
+ rc = cifs_reopen_file(open_file, true);
+ if (rc == -EAGAIN)
+ continue;
+ else if (rc)
+ break;
+ }
+
rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
&rsize, credits);
if (rc)
@@ -3438,9 +3453,8 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
if (!rc) {
if (rdata->cfile->invalidHandle)
- rc = cifs_reopen_file(rdata->cfile, true);
-
- if (!rc)
+ rc = -EAGAIN;
+ else
rc = server->ops->async_readv(rdata);
}
@@ -4127,6 +4141,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct cifs_credits credits_on_stack;
struct cifs_credits *credits = &credits_on_stack;
+ if (open_file->invalidHandle) {
+ rc = cifs_reopen_file(open_file, true);
+ if (rc == -EAGAIN)
+ continue;
+ else if (rc)
+ break;
+ }
+
rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
&rsize, credits);
if (rc)
@@ -4185,9 +4207,8 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
if (!rc) {
if (rdata->cfile->invalidHandle)
- rc = cifs_reopen_file(rdata->cfile, true);
-
- if (!rc)
+ rc = -EAGAIN;
+ else
rc = server->ops->async_readv(rdata);
}