| From 689c3db4d57a73bee6c5ad7797fce7b54d32a87c Mon Sep 17 00:00:00 2001 |
| From: Pavel Shilovsky <pshilovsky@samba.org> |
| Date: Thu, 11 Jul 2013 11:17:45 +0400 |
| Subject: CIFS: Fix a deadlock when a file is reopened |
| |
| From: Pavel Shilovsky <pshilovsky@samba.org> |
| |
| commit 689c3db4d57a73bee6c5ad7797fce7b54d32a87c upstream. |
| |
| If we request reading or writing on a file that needs to be |
| reopened, it causes the deadlock: we are already holding rw |
| semaphore for reading and then we try to acquire it for writing |
| in cifs_relock_file. Fix this by acquiring the semaphore for |
| reading in cifs_relock_file due to we don't make any changes in |
| locks and don't need a write access. |
| |
| Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> |
| Acked-by: Jeff Layton <jlayton@redhat.com> |
| Signed-off-by: Steve French <smfrench@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/cifs/file.c | 9 ++++----- |
| 1 file changed, 4 insertions(+), 5 deletions(-) |
| |
| --- a/fs/cifs/file.c |
| +++ b/fs/cifs/file.c |
| @@ -557,11 +557,10 @@ cifs_relock_file(struct cifsFileInfo *cf |
| struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| int rc = 0; |
| |
| - /* we are going to update can_cache_brlcks here - need a write access */ |
| - down_write(&cinode->lock_sem); |
| + down_read(&cinode->lock_sem); |
| if (cinode->can_cache_brlcks) { |
| - /* can cache locks - no need to push them */ |
| - up_write(&cinode->lock_sem); |
| + /* can cache locks - no need to relock */ |
| + up_read(&cinode->lock_sem); |
| return rc; |
| } |
| |
| @@ -572,7 +571,7 @@ cifs_relock_file(struct cifsFileInfo *cf |
| else |
| rc = tcon->ses->server->ops->push_mand_locks(cfile); |
| |
| - up_write(&cinode->lock_sem); |
| + up_read(&cinode->lock_sem); |
| return rc; |
| } |
| |