| From eae4f373b3685e8f7be5b4d5b5d5a355e4c2c20b Mon Sep 17 00:00:00 2001 |
| From: Germano Percossi <germano.percossi@citrix.com> |
| Date: Fri, 7 Apr 2017 12:29:38 +0100 |
| Subject: [PATCH] CIFS: store results of cifs_reopen_file to avoid infinite |
| wait |
| |
| commit 1fa839b4986d648b907d117275869a0e46c324b9 upstream. |
| |
| This fixes Continuous Availability when errors during |
| file reopen are encountered. |
| |
| cifs_user_readv and cifs_user_writev would wait for ever if |
| results of cifs_reopen_file are not stored and for later inspection. |
| |
| In fact, results are checked and, in case of errors, a chain |
| of function calls leading to reads and writes to be scheduled in |
| a separate thread is skipped. |
| These threads will wake up the corresponding waiters once reads |
| and writes are done. |
| |
| However, given the return value is not stored, when rc is checked |
| for errors a previous one (always zero) is inspected instead. |
| This leads to pending reads/writes added to the list, making |
| cifs_user_readv and cifs_user_writev wait for ever. |
| |
| Signed-off-by: Germano Percossi <germano.percossi@citrix.com> |
| Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> |
| CC: Stable <stable@vger.kernel.org> |
| Signed-off-by: Steve French <smfrench@gmail.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/cifs/file.c b/fs/cifs/file.c |
| index 605438afe7ef..3243348d1643 100644 |
| --- a/fs/cifs/file.c |
| +++ b/fs/cifs/file.c |
| @@ -2553,7 +2553,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from, |
| wdata->credits = credits; |
| |
| if (!wdata->cfile->invalidHandle || |
| - !cifs_reopen_file(wdata->cfile, false)) |
| + !(rc = cifs_reopen_file(wdata->cfile, false))) |
| rc = server->ops->async_writev(wdata, |
| cifs_uncached_writedata_release); |
| if (rc) { |
| @@ -2955,7 +2955,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file, |
| rdata->credits = credits; |
| |
| if (!rdata->cfile->invalidHandle || |
| - !cifs_reopen_file(rdata->cfile, true)) |
| + !(rc = cifs_reopen_file(rdata->cfile, true))) |
| rc = server->ops->async_readv(rdata); |
| error: |
| if (rc) { |
| @@ -3530,7 +3530,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, |
| } |
| |
| if (!rdata->cfile->invalidHandle || |
| - !cifs_reopen_file(rdata->cfile, true)) |
| + !(rc = cifs_reopen_file(rdata->cfile, true))) |
| rc = server->ops->async_readv(rdata); |
| if (rc) { |
| add_credits_and_wake_if(server, rdata->credits, 0); |
| -- |
| 2.12.0 |
| |