Btrfs: fix deadlock on page lock when doing auto-defragment
authorMiao Xie <miaox@cn.fujitsu.com>
Thu, 16 Feb 2012 07:01:24 +0000 (15:01 +0800)
committerDavid Sterba <dsterba@suse.cz>
Thu, 16 Feb 2012 16:23:16 +0000 (17:23 +0100)
commit600a45e1d5e376f679ff9ecc4ce9452710a6d27c
treec4bf84eee1db132b5ff18700b95da8426a909f2f
parent013bd4c336ad0d30e9e41f9cff0dbc1858934e75
Btrfs: fix deadlock on page lock when doing auto-defragment

When I ran xfstests circularly on a auto-defragment btrfs, the deadlock
happened.

Steps to reproduce:
[tty0]
 # export MOUNT_OPTIONS="-o autodefrag"
 # export TEST_DEV=<partition1>
 # export TEST_DIR=<mountpoint1>
 # export SCRATCH_DEV=<partition2>
 # export SCRATCH_MNT=<mountpoint2>
 # while [ 1 ]
 > do
 > ./check 091 127 263
 > sleep 1
 > done
[tty1]
 # while [ 1 ]
 > do
 > echo 3 > /proc/sys/vm/drop_caches
 > done

Several hours later, the test processes will hang on, and the deadlock will
happen on page lock.

The reason is that:
  Auto defrag task Flush thread Test task
btrfs_writepages()
  add ordered extent
  (including page 1, 2)
  set page 1 writeback
  set page 2 writeback
endio_fn()
  end page 2 writeback
release page 2
lock page 1
alloc and lock page 2
page 2 is not uptodate
  btrfs_readpage()
    start ordered extent()
    btrfs_writepages()
      try  to lock page 1

so deadlock happens.

Fix this bug by unlocking the page which is in writeback, and re-locking it
after the writeback end.

Signed-off-by: Miao Xie <miax@cn.fujitsu.com>
fs/btrfs/ioctl.c