linux/fs/btrfs
Nikolay Borisov 9e78c0e742 btrfs: Correctly handle empty trees in find_first_clear_extent_bit
commit 5750c37523 upstream.

Raviu reported that running his regular fs_trim segfaulted with the
following backtrace:

[  237.525947] assertion failed: prev, in ../fs/btrfs/extent_io.c:1595
[  237.525984] ------------[ cut here ]------------
[  237.525985] kernel BUG at ../fs/btrfs/ctree.h:3117!
[  237.525992] invalid opcode: 0000 [#1] SMP PTI
[  237.525998] CPU: 4 PID: 4423 Comm: fstrim Tainted: G     U     OE     5.4.14-8-vanilla #1
[  237.526001] Hardware name: ASUSTeK COMPUTER INC.
[  237.526044] RIP: 0010:assfail.constprop.58+0x18/0x1a [btrfs]
[  237.526079] Call Trace:
[  237.526120]  find_first_clear_extent_bit+0x13d/0x150 [btrfs]
[  237.526148]  btrfs_trim_fs+0x211/0x3f0 [btrfs]
[  237.526184]  btrfs_ioctl_fitrim+0x103/0x170 [btrfs]
[  237.526219]  btrfs_ioctl+0x129a/0x2ed0 [btrfs]
[  237.526227]  ? filemap_map_pages+0x190/0x3d0
[  237.526232]  ? do_filp_open+0xaf/0x110
[  237.526238]  ? _copy_to_user+0x22/0x30
[  237.526242]  ? cp_new_stat+0x150/0x180
[  237.526247]  ? do_vfs_ioctl+0xa4/0x640
[  237.526278]  ? btrfs_ioctl_get_supported_features+0x30/0x30 [btrfs]
[  237.526283]  do_vfs_ioctl+0xa4/0x640
[  237.526288]  ? __do_sys_newfstat+0x3c/0x60
[  237.526292]  ksys_ioctl+0x70/0x80
[  237.526297]  __x64_sys_ioctl+0x16/0x20
[  237.526303]  do_syscall_64+0x5a/0x1c0
[  237.526310]  entry_SYSCALL_64_after_hwframe+0x49/0xbe

That was due to btrfs_fs_device::aloc_tree being empty. Initially I
thought this wasn't possible and as a percaution have put the assert in
find_first_clear_extent_bit. Turns out this is indeed possible and could
happen when a file system with SINGLE data/metadata profile has a 2nd
device added. Until balance is run or a new chunk is allocated on this
device it will be completely empty.

In this case find_first_clear_extent_bit should return the full range
[0, -1ULL] and let the caller handle this i.e for trim the end will be
capped at the size of actual device.

Link: https://lore.kernel.org/linux-btrfs/izW2WNyvy1dEDweBICizKnd2KDwDiDyY2EYQr4YCwk7pkuIpthx-JRn65MPBde00ND6V0_Lh8mW0kZwzDiLDv25pUYWxkskWNJnVP0kgdMA=@protonmail.com/
Fixes: 45bfcfc168 ("btrfs: Implement find_first_clear_extent_bit")
CC: stable@vger.kernel.org # 5.2+
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-02-11 04:35:34 -08:00
..
tests btrfs: Correctly handle empty trees in find_first_clear_extent_bit 2020-02-11 04:35:34 -08:00
Kconfig
Makefile
acl.c
async-thread.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
async-thread.h btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
backref.c
backref.h
block-group.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
block-group.h
block-rsv.c
block-rsv.h
btrfs_inode.h
check-integrity.c
check-integrity.h
compression.c
compression.h
ctree.c Btrfs: fix race between adding and putting tree mod seq elements and nodes 2020-02-11 04:35:34 -08:00
ctree.h Btrfs: fix race between adding and putting tree mod seq elements and nodes 2020-02-11 04:35:34 -08:00
delalloc-space.c Btrfs: fix qgroup double free after failure to reserve metadata for delalloc 2019-10-17 20:13:44 +02:00
delalloc-space.h
delayed-inode.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
delayed-inode.h
delayed-ref.c Btrfs: fix race between adding and putting tree mod seq elements and nodes 2020-02-11 04:35:34 -08:00
delayed-ref.h
dev-replace.c
dev-replace.h
dir-item.c
disk-io.c Btrfs: fix race between adding and putting tree mod seq elements and nodes 2020-02-11 04:35:34 -08:00
disk-io.h
export.c
export.h
extent-tree.c btrfs: handle error in btrfs_cache_block_group 2020-01-12 12:21:30 +01:00
extent_io.c btrfs: Correctly handle empty trees in find_first_clear_extent_bit 2020-02-11 04:35:34 -08:00
extent_io.h
extent_map.c
extent_map.h
file-item.c Btrfs: fix missing data checksums after replaying a log tree 2019-12-31 16:41:58 +01:00
file.c btrfs: simplify inode locking for RWF_NOWAIT 2020-01-17 19:48:32 +01:00
free-space-cache.c btrfs: check page->mapping when loading free space cache 2019-12-17 19:56:02 +01:00
free-space-cache.h
free-space-tree.c
free-space-tree.h
inode-item.c
inode-map.c btrfs: qgroup: Always free PREALLOC META reserve in btrfs_delalloc_release_extents() 2019-10-15 18:50:07 +02:00
inode-map.h
inode.c btrfs: fix invalid removal of root ref 2020-01-23 08:22:40 +01:00
ioctl.c Btrfs: make deduplication with range including the last block work 2020-02-11 04:35:33 -08:00
locking.c
locking.h
lzo.c
misc.h
ordered-data.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
ordered-data.h
orphan.c
print-tree.c
print-tree.h
props.c
props.h
qgroup.c btrfs: fix memory leak in qgroup accounting 2020-01-23 08:22:41 +01:00
qgroup.h
raid56.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
raid56.h
rcu-string.h
reada.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
ref-verify.c
ref-verify.h
relocation.c btrfs: relocation: fix reloc_root lifespan and access 2020-01-23 08:22:40 +01:00
root-tree.c btrfs: do not delete mismatched root refs 2020-01-23 08:22:40 +01:00
scrub.c btrfs: get rid of unique workqueue helper functions 2020-01-09 10:20:06 +01:00
send.c btrfs: send: remove WARN_ON for readonly mount 2019-12-31 16:41:59 +01:00
send.h
space-info.c Btrfs: fix race leading to metadata space leak after task received signal 2019-10-25 19:11:34 +02:00
space-info.h
struct-funcs.c
super.c btrfs: do not zero f_bavail if we have available space 2020-02-05 21:22:52 +00:00
sysfs.c
sysfs.h
transaction.c btrfs: drop log root for dropped roots 2020-02-11 04:35:33 -08:00
transaction.h
tree-checker.c Btrfs: make tree checker detect checksum items with overlapping ranges 2019-12-31 16:41:55 +01:00
tree-checker.h
tree-defrag.c
tree-log.c Btrfs: fix infinite loop during fsync after rename operations 2020-02-11 04:35:33 -08:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c btrfs: handle ENOENT in btrfs_uuid_tree_iterate 2019-12-31 16:42:05 +01:00
volumes.c btrfs: Handle another split brain scenario with metadata uuid feature 2020-02-11 04:35:28 -08:00
volumes.h btrfs: Remove btrfs_bio::flags member 2019-12-17 19:56:06 +01:00
xattr.c
xattr.h
zlib.c
zstd.c