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 <holding tree lock> dir_emit <page fault> 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 <hang> Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> [ copy the deadlock scenario to changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:

committed by
David Sterba

parent
8d8aafeea2
commit
23b5ec7494
@@ -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;
|
||||
|
Reference in New Issue
Block a user