| From ee8a1a8b160a87dc3a9c81a86796aa4db85ea815 Mon Sep 17 00:00:00 2001 |
| From: Peng Tao <tao.peng@primarydata.com> |
| Date: Tue, 20 Jan 2015 07:44:29 +0800 |
| Subject: nfs: fix dio deadlock when O_DIRECT flag is flipped |
| |
| From: Peng Tao <tao.peng@primarydata.com> |
| |
| commit ee8a1a8b160a87dc3a9c81a86796aa4db85ea815 upstream. |
| |
| We only support swap file calling nfs_direct_IO. However, application |
| might be able to get to nfs_direct_IO if it toggles O_DIRECT flag |
| during IO and it can deadlock because we grab inode->i_mutex in |
| nfs_file_direct_write(). So return 0 for such case. Then the generic |
| layer will fall back to buffer IO. |
| |
| Signed-off-by: Peng Tao <tao.peng@primarydata.com> |
| Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/nfs/direct.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/fs/nfs/direct.c |
| +++ b/fs/nfs/direct.c |
| @@ -212,6 +212,12 @@ static int nfs_direct_cmp_commit_data_ve |
| */ |
| ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) |
| { |
| + struct inode *inode = iocb->ki_filp->f_mapping->host; |
| + |
| + /* we only support swap file calling nfs_direct_IO */ |
| + if (!IS_SWAPFILE(inode)) |
| + return 0; |
| + |
| #ifndef CONFIG_NFS_SWAP |
| dprintk("NFS: nfs_direct_IO (%pD) off/no(%Ld/%lu) EINVAL\n", |
| iocb->ki_filp, (long long) pos, iter->nr_segs); |