btrfs: fix possible deadlock by clearing __GFP_FS flag
authorMiao Xie <miaox@cn.fujitsu.com>
Sun, 27 Mar 2011 08:07:36 +0000 (16:07 +0800)
committerroot <Chris Mason chris.mason@oracle.com>
Mon, 28 Mar 2011 09:37:58 +0000 (05:37 -0400)
commit1561deda687eef0e95065f1268d680ddc5976ee7
tree3ad8a8305fc3ca960cf7ef472f64d9cfef246ffd
parentc055e99eea6e4f614267632fac546e7896c0227b
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>
fs/btrfs/disk-io.c
fs/btrfs/inode.c