• F
    Btrfs: fix inode eviction infinite loop after cloning into it · ccccf3d6
    Filipe Manana 提交于
    If we attempt to clone a 0 length region into a file we can end up
    inserting a range in the inode's extent_io tree with a start offset
    that is greater then the end offset, which triggers immediately the
    following warning:
    
    [ 3914.619057] WARNING: CPU: 17 PID: 4199 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
    [ 3914.620886] BTRFS: end < start 4095 4096
    (...)
    [ 3914.638093] Call Trace:
    [ 3914.638636]  [<ffffffff81425fd9>] dump_stack+0x4c/0x65
    [ 3914.639620]  [<ffffffff81045390>] warn_slowpath_common+0xa1/0xbb
    [ 3914.640789]  [<ffffffffa03ca44f>] ? insert_state+0x4b/0x10b [btrfs]
    [ 3914.642041]  [<ffffffff810453f0>] warn_slowpath_fmt+0x46/0x48
    [ 3914.643236]  [<ffffffffa03ca44f>] insert_state+0x4b/0x10b [btrfs]
    [ 3914.644441]  [<ffffffffa03ca729>] __set_extent_bit+0x107/0x3f4 [btrfs]
    [ 3914.645711]  [<ffffffffa03cb256>] lock_extent_bits+0x65/0x1bf [btrfs]
    [ 3914.646914]  [<ffffffff8142b2fb>] ? _raw_spin_unlock+0x28/0x33
    [ 3914.648058]  [<ffffffffa03cbac4>] ? test_range_bit+0xcc/0xde [btrfs]
    [ 3914.650105]  [<ffffffffa03cb3c3>] lock_extent+0x13/0x15 [btrfs]
    [ 3914.651361]  [<ffffffffa03db39e>] lock_extent_range+0x3d/0xcd [btrfs]
    [ 3914.652761]  [<ffffffffa03de1fe>] btrfs_ioctl_clone+0x278/0x388 [btrfs]
    [ 3914.654128]  [<ffffffff811226dd>] ? might_fault+0x58/0xb5
    [ 3914.655320]  [<ffffffffa03e0909>] btrfs_ioctl+0xb51/0x2195 [btrfs]
    (...)
    [ 3914.669271] ---[ end trace 14843d3e2e622fc1 ]---
    
    This later makes the inode eviction handler enter an infinite loop that
    keeps dumping the following warning over and over:
    
    [ 3915.117629] WARNING: CPU: 22 PID: 4228 at fs/btrfs/extent_io.c:435 insert_state+0x4b/0x10b [btrfs]()
    [ 3915.119913] BTRFS: end < start 4095 4096
    (...)
    [ 3915.137394] Call Trace:
    [ 3915.137913]  [<ffffffff81425fd9>] dump_stack+0x4c/0x65
    [ 3915.139154]  [<ffffffff81045390>] warn_slowpath_common+0xa1/0xbb
    [ 3915.140316]  [<ffffffffa03ca44f>] ? insert_state+0x4b/0x10b [btrfs]
    [ 3915.141505]  [<ffffffff810453f0>] warn_slowpath_fmt+0x46/0x48
    [ 3915.142709]  [<ffffffffa03ca44f>] insert_state+0x4b/0x10b [btrfs]
    [ 3915.143849]  [<ffffffffa03ca729>] __set_extent_bit+0x107/0x3f4 [btrfs]
    [ 3915.145120]  [<ffffffffa038c1e3>] ? btrfs_kill_super+0x17/0x23 [btrfs]
    [ 3915.146352]  [<ffffffff811548f6>] ? deactivate_locked_super+0x3b/0x50
    [ 3915.147565]  [<ffffffffa03cb256>] lock_extent_bits+0x65/0x1bf [btrfs]
    [ 3915.148785]  [<ffffffff8142b7e2>] ? _raw_write_unlock+0x28/0x33
    [ 3915.149931]  [<ffffffffa03bc325>] btrfs_evict_inode+0x196/0x482 [btrfs]
    [ 3915.151154]  [<ffffffff81168904>] evict+0xa0/0x148
    [ 3915.152094]  [<ffffffff811689e5>] dispose_list+0x39/0x43
    [ 3915.153081]  [<ffffffff81169564>] evict_inodes+0xdc/0xeb
    [ 3915.154062]  [<ffffffff81154418>] generic_shutdown_super+0x49/0xef
    [ 3915.155193]  [<ffffffff811546d1>] kill_anon_super+0x13/0x1e
    [ 3915.156274]  [<ffffffffa038c1e3>] btrfs_kill_super+0x17/0x23 [btrfs]
    (...)
    [ 3915.167404] ---[ end trace 14843d3e2e622fc2 ]---
    
    So just bail out of the clone ioctl if the length of the region to clone
    is zero, without locking any extent range, in order to prevent this issue
    (same behaviour as a pwrite with a 0 length for example).
    
    This is trivial to reproduce. For example, the steps for the test I just
    made for fstests:
    
      mkfs.btrfs -f SCRATCH_DEV
      mount SCRATCH_DEV $SCRATCH_MNT
    
      touch $SCRATCH_MNT/foo
      touch $SCRATCH_MNT/bar
    
      $CLONER_PROG -s 0 -d 4096 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
      umount $SCRATCH_MNT
    
    A test case for fstests follows soon.
    
    CC: <stable@vger.kernel.org>
    Signed-off-by: NFilipe Manana <fdmanana@suse.com>
    Reviewed-by: NOmar Sandoval <osandov@osandov.com>
    Signed-off-by: NChris Mason <clm@fb.com>
    ccccf3d6
ioctl.c 128.3 KB