diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2011-03-27 16:07:36 +0800 |
---|---|---|
committer | root <Chris Mason chris.mason@oracle.com> | 2011-03-28 05:37:58 -0400 |
commit | 1561deda687eef0e95065f1268d680ddc5976ee7 (patch) | |
tree | 3ad8a8305fc3ca960cf7ef472f64d9cfef246ffd /fs/btrfs/disk-io.c | |
parent | c055e99eea6e4f614267632fac546e7896c0227b (diff) | |
download | linux-1561deda687eef0e95065f1268d680ddc5976ee7.tar.gz linux-1561deda687eef0e95065f1268d680ddc5976ee7.tar.bz2 linux-1561deda687eef0e95065f1268d680ddc5976ee7.zip |
btrfs: fix possible deadlock by clearing __GFP_FS flag
Using the GFP_HIGHUSER_MOVABLE flag to allocate the metadata's page may cause
deadlock.
Task1
open()
...
btrfs_search_slot()
...
btrfs_cow_block()
...
alloc_page()
wait for reclaiming
shrink_slab()
...
shrink_icache_memory()
...
btrfs_evict_inode()
...
btrfs_search_slot()
If the path is locked by task1, the deadlock happens.
So the btree's page cache is different with the file's page cache, it can not
allocate pages by GFP_HIGHUSER_MOVABLE flag, we must clear __GFP_FS flag in
GFP_HIGHUSER_MOVABLE flag.
Reported-by: Itaru Kitayama <kitayama@cl.bb4u.ne.jp>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b3fc8475870f..5cf3aa7b125c 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1724,6 +1724,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, goto fail_bdi; } + fs_info->btree_inode->i_mapping->flags &= ~__GFP_FS; + INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); INIT_LIST_HEAD(&fs_info->trans_list); INIT_LIST_HEAD(&fs_info->dead_roots); |