| From 11f07b9db0facc3b6fcced9e8e645eefb02cf71b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 9 Oct 2020 09:32:56 +1000 |
| Subject: cifs: handle -EINTR in cifs_setattr |
| |
| From: Ronnie Sahlberg <lsahlber@redhat.com> |
| |
| [ Upstream commit c6cc4c5a72505a0ecefc9b413f16bec512f38078 ] |
| |
| RHBZ: 1848178 |
| |
| Some calls that set attributes, like utimensat(), are not supposed to return |
| -EINTR and thus do not have handlers for this in glibc which causes us |
| to leak -EINTR to the applications which are also unprepared to handle it. |
| |
| For example tar will break if utimensat() return -EINTR and abort unpacking |
| the archive. Other applications may break too. |
| |
| To handle this we add checks, and retry, for -EINTR in cifs_setattr() |
| |
| Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> |
| Signed-off-by: Steve French <stfrench@microsoft.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/cifs/inode.c | 13 +++++++++---- |
| 1 file changed, 9 insertions(+), 4 deletions(-) |
| |
| diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c |
| index 1f75b25e559a7..daec31be85718 100644 |
| --- a/fs/cifs/inode.c |
| +++ b/fs/cifs/inode.c |
| @@ -2883,13 +2883,18 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) |
| { |
| struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); |
| struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); |
| + int rc, retries = 0; |
| |
| - if (pTcon->unix_ext) |
| - return cifs_setattr_unix(direntry, attrs); |
| - |
| - return cifs_setattr_nounix(direntry, attrs); |
| + do { |
| + if (pTcon->unix_ext) |
| + rc = cifs_setattr_unix(direntry, attrs); |
| + else |
| + rc = cifs_setattr_nounix(direntry, attrs); |
| + retries++; |
| + } while (is_retryable_error(rc) && retries < 2); |
| |
| /* BB: add cifs_setattr_legacy for really old servers */ |
| + return rc; |
| } |
| |
| #if 0 |
| -- |
| 2.27.0 |
| |