Taking the i_rwsem for swap IO triggers lockdep warnings regarding possible deadlocks with "fs_reclaim". These deadlocks could, I believe, eventuate if a buffered read on the swapfile was attempted. We don't need coherence with the page cache for a swap file, and buffered writes are forbidden anyway. There is no other need for i_rwsem during direct IO. So don't take the rwsem or set the NFS_INO_ODIRECT flag during IO to the swap file. Signed-off-by: NeilBrown <neilb@xxxxxxx> --- fs/nfs/io.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfs/io.c b/fs/nfs/io.c index b5551ed8f648..83b4dfbb826d 100644 --- a/fs/nfs/io.c +++ b/fs/nfs/io.c @@ -118,11 +118,18 @@ static void nfs_block_buffered(struct nfs_inode *nfsi, struct inode *inode) * NFS_INO_ODIRECT. * Note that buffered writes and truncates both take a write lock on * inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT. + * + * When inode IS_SWAPFILE we ignore the flag and don't take the rwsem + * as it triggers lockdep warnings and possible deadlocks. + * bufferred writes are forbidden anyway, and buffered reads will not + * be coherent. */ void nfs_start_io_direct(struct inode *inode) { struct nfs_inode *nfsi = NFS_I(inode); + if (IS_SWAPFILE(inode)) + return; /* Be an optimist! */ down_read(&inode->i_rwsem); if (test_bit(NFS_INO_ODIRECT, &nfsi->flags) != 0) @@ -144,5 +151,7 @@ nfs_start_io_direct(struct inode *inode) void nfs_end_io_direct(struct inode *inode) { + if (IS_SWAPFILE(inode)) + return; up_read(&inode->i_rwsem); }