Btrfs: serialize unlocked dio reads with truncate
authorMiao Xie <miaox@cn.fujitsu.com>
Fri, 8 Feb 2013 07:01:08 +0000 (07:01 +0000)
committerJosef Bacik <jbacik@fusionio.com>
Wed, 20 Feb 2013 17:59:47 +0000 (12:59 -0500)
commit2e60a51e62185cce48758e596ae7cb2da673b58f
treebdbbac16110a3eeda8732c3ffb38a440204e2831
parent0934856d4697e63c14056375e26e3bd6e8ebd34b
Btrfs: serialize unlocked dio reads with truncate

Currently, we can do unlocked dio reads, but the following race
is possible:

dio_read_task truncate_task
->btrfs_setattr()
->btrfs_direct_IO
    ->__blockdev_direct_IO
      ->btrfs_get_block
  ->btrfs_truncate()
 #alloc truncated blocks
 #to other inode
      ->submit_io()
     #INFORMATION LEAK

In order to avoid this problem, we must serialize unlocked dio reads with
truncate. There are two approaches:
- use extent lock to protect the extent that we truncate
- use inode_dio_wait() to make sure the truncating task will wait for
  the read DIO.

If we use the 1st one, we will meet the endless truncation problem due to
the nonlocked read DIO after we implement the nonlocked write DIO. It is
because we still need invoke inode_dio_wait() avoid the race between write
DIO and truncation. By that time, we have to introduce

  btrfs_inode_{block, resume}_nolock_dio()

again. That is we have to implement this patch again, so I choose the 2nd
way to fix the problem.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
fs/btrfs/btrfs_inode.h
fs/btrfs/inode.c