From 23b5ec74943f44378b68c0edd8e210a86318ea5e Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 24 Jul 2017 15:14:25 -0400 Subject: btrfs: fix readdir deadlock with pagefault Readdir does dir_emit while under the btree lock. dir_emit can trigger the page fault which means we can deadlock. Fix this by allocating a buffer on opening a directory and copying the readdir into this buffer and doing dir_emit from outside of the tree lock. Thread A readdir dir_emit down_read(mmap_sem) Thread B mmap write down_write(mmap_sem) page_mkwrite wait_ordered_extents Process C finish_ordered_extent insert_reserved_file_extent try to lock leaf Signed-off-by: Josef Bacik Reviewed-by: David Sterba [ copy the deadlock scenario to changelog ] Signed-off-by: David Sterba --- fs/btrfs/ctree.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs/btrfs/ctree.h') diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b9d5d95bc583..a3db2b1738aa 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1264,6 +1264,11 @@ struct btrfs_root { atomic64_t qgroup_meta_rsv; }; +struct btrfs_file_private { + struct btrfs_trans_handle *trans; + void *filldir_buf; +}; + static inline u32 btrfs_inode_sectorsize(const struct inode *inode) { return btrfs_sb(inode->i_sb)->sectorsize; -- cgit