[PATCH 18/23] CIFS: Reopen file before get SMB2 MTU credits for async IO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/file.c | 39 ++++++++++++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e793b55..ef85a3c 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);
 		}
 
@@ -4129,6 +4143,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)
@@ -4187,9 +4209,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);
 		}
 
-- 
2.7.4




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux