android_kernel_oneplus_msm8998/fs/btrfs
Qu Wenruo 02e48c4d57 btrfs: Don't remove block group that still has pinned down bytes
[ Upstream commit 43794446548730ac8461be30bbe47d5d027d1d16 ]

[BUG]
Under certain KVM load and LTP tests, it is possible to hit the
following calltrace if quota is enabled:

BTRFS critical (device vda2): unable to find logical 8820195328 length 4096
BTRFS critical (device vda2): unable to find logical 8820195328 length 4096

WARNING: CPU: 0 PID: 49 at ../block/blk-core.c:172 blk_status_to_errno+0x1a/0x30
CPU: 0 PID: 49 Comm: kworker/u2:1 Not tainted 4.12.14-15-default #1 SLE15 (unreleased)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs]
task: ffff9f827b340bc0 task.stack: ffffb4f8c0304000
RIP: 0010:blk_status_to_errno+0x1a/0x30
Call Trace:
 submit_extent_page+0x191/0x270 [btrfs]
 ? btrfs_create_repair_bio+0x130/0x130 [btrfs]
 __do_readpage+0x2d2/0x810 [btrfs]
 ? btrfs_create_repair_bio+0x130/0x130 [btrfs]
 ? run_one_async_done+0xc0/0xc0 [btrfs]
 __extent_read_full_page+0xe7/0x100 [btrfs]
 ? run_one_async_done+0xc0/0xc0 [btrfs]
 read_extent_buffer_pages+0x1ab/0x2d0 [btrfs]
 ? run_one_async_done+0xc0/0xc0 [btrfs]
 btree_read_extent_buffer_pages+0x94/0xf0 [btrfs]
 read_tree_block+0x31/0x60 [btrfs]
 read_block_for_search.isra.35+0xf0/0x2e0 [btrfs]
 btrfs_search_slot+0x46b/0xa00 [btrfs]
 ? kmem_cache_alloc+0x1a8/0x510
 ? btrfs_get_token_32+0x5b/0x120 [btrfs]
 find_parent_nodes+0x11d/0xeb0 [btrfs]
 ? leaf_space_used+0xb8/0xd0 [btrfs]
 ? btrfs_leaf_free_space+0x49/0x90 [btrfs]
 ? btrfs_find_all_roots_safe+0x93/0x100 [btrfs]
 btrfs_find_all_roots_safe+0x93/0x100 [btrfs]
 btrfs_find_all_roots+0x45/0x60 [btrfs]
 btrfs_qgroup_trace_extent_post+0x20/0x40 [btrfs]
 btrfs_add_delayed_data_ref+0x1a3/0x1d0 [btrfs]
 btrfs_alloc_reserved_file_extent+0x38/0x40 [btrfs]
 insert_reserved_file_extent.constprop.71+0x289/0x2e0 [btrfs]
 btrfs_finish_ordered_io+0x2f4/0x7f0 [btrfs]
 ? pick_next_task_fair+0x2cd/0x530
 ? __switch_to+0x92/0x4b0
 btrfs_worker_helper+0x81/0x300 [btrfs]
 process_one_work+0x1da/0x3f0
 worker_thread+0x2b/0x3f0
 ? process_one_work+0x3f0/0x3f0
 kthread+0x11a/0x130
 ? kthread_create_on_node+0x40/0x40
 ret_from_fork+0x35/0x40

BTRFS critical (device vda2): unable to find logical 8820195328 length 16384
BTRFS: error (device vda2) in btrfs_finish_ordered_io:3023: errno=-5 IO failure
BTRFS info (device vda2): forced readonly
BTRFS error (device vda2): pending csums is 2887680

[CAUSE]
It's caused by race with block group auto removal:

- There is a meta block group X, which has only one tree block
  The tree block belongs to fs tree 257.
- In current transaction, some operation modified fs tree 257
  The tree block gets COWed, so the block group X is empty, and marked
  as unused, queued to be deleted.
- Some workload (like fsync) wakes up cleaner_kthread()
  Which will call btrfs_delete_unused_bgs() to remove unused block
  groups.
  So block group X along its chunk map get removed.
- Some delalloc work finished for fs tree 257
  Quota needs to get the original reference of the extent, which will
  read tree blocks of commit root of 257.
  Then since the chunk map gets removed, the above warning gets
  triggered.

[FIX]
Just let btrfs_delete_unused_bgs() skip block group which still has
pinned bytes.

However there is a minor side effect: currently we only queue empty
blocks at update_block_group(), and such empty block group with pinned
bytes won't go through update_block_group() again, such block group
won't be removed, until it gets new extent allocated and removed.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-09-15 09:40:40 +02:00
..
tests btrfs: tests/qgroup: Fix wrong tree backref level 2018-05-30 07:49:09 +02:00
acl.c btrfs: preserve i_mode if __btrfs_set_acl() fails 2018-03-11 16:19:47 +01:00
async-thread.c btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
async-thread.h btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
backref.c Btrfs: fix hang on extent buffer lock caused by the inode_paths ioctl 2016-02-25 12:01:15 -08:00
backref.h
btrfs_inode.h Btrfs: Direct I/O: Fix space accounting 2015-09-21 13:47:55 -07:00
check-integrity.c Merge branch 'cleanups/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4 2015-10-21 18:21:40 -07:00
check-integrity.h
compression.c btrfs: assign error values to the correct bio structs 2016-10-22 12:26:54 +02:00
compression.h
ctree.c btrfs: Fix out of bounds access in btrfs_search_slot 2018-05-30 07:48:54 +02:00
ctree.h btrfs: store and load values of stripes_min/stripes_max in balance status item 2017-01-06 11:16:06 +01:00
delayed-inode.c btrfs: limit async_work allocation and worker func duration 2017-01-06 11:16:06 +01:00
delayed-inode.h btrfs: properly set the termination value of ctx->pos in readdir 2016-02-25 12:01:15 -08:00
delayed-ref.c btrfs: qgroup: Fix a race in delayed_ref which leads to abort trans 2015-10-26 19:44:39 -07:00
delayed-ref.h btrfs: qgroup: Fix a race in delayed_ref which leads to abort trans 2015-10-26 19:44:39 -07:00
dev-replace.c btrfs: replace: Reset on-disk dev stats value after replace 2018-09-15 09:40:40 +02:00
dev-replace.h
dir-item.c
disk-io.c x86/cpufeature: Replace the old static_cpu_has() with safe variant 2018-07-17 11:31:44 +02:00
disk-io.h Btrfs: add btrfs_read_dev_one_super() to read one specific SB 2015-10-01 17:29:38 +02:00
export.c BTRFS: support NFSv2 export 2015-10-06 06:55:23 -07:00
export.h
extent-tree.c btrfs: Don't remove block group that still has pinned down bytes 2018-09-15 09:40:40 +02:00
extent-tree.h
extent_io.c btrfs: fix incorrect error return ret being passed to mapping_set_error 2018-04-13 19:50:06 +02:00
extent_io.h btrfs: qgroup: Introduce btrfs_qgroup_reserve_data function 2015-10-21 18:37:45 -07:00
extent_map.c
extent_map.h
file-item.c
file.c Btrfs: set plug for fsync 2018-05-30 07:48:54 +02:00
free-space-cache.c btrfs: fix deadlock when writing out space cache 2018-02-03 17:04:27 +01:00
free-space-cache.h Btrfs: keep track of largest extent in bitmaps 2015-10-21 18:55:40 -07:00
hash.c
hash.h
inode-item.c Btrfs: consolidate btrfs_error() to btrfs_std_error() 2015-09-29 16:30:00 +02:00
inode-map.c Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-03-03 15:07:12 -08:00
inode-map.h Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-03-03 15:07:12 -08:00
inode.c Btrfs: fix unexpected cow in run_delalloc_nocow 2018-07-03 11:21:35 +02:00
ioctl.c Btrfs: fix clone vs chattr NODATASUM race 2018-07-03 11:21:30 +02:00
Kconfig
locking.c btrfs: comment the rest of implicit barriers before waitqueue_active 2015-10-10 18:42:00 +02:00
locking.h
lzo.c
Makefile
math.h
ordered-data.c Btrfs: change how we wait for pending ordered extents 2015-10-21 18:51:40 -07:00
ordered-data.h Btrfs: change how we wait for pending ordered extents 2015-10-21 18:51:40 -07:00
orphan.c
print-tree.c
print-tree.h
props.c btrfs: cleanup iterating over prop_handlers array 2015-10-21 18:28:48 +02:00
props.h
qgroup.c btrfs: qgroup: Finish rescan when hit the last leaf of extent tree 2018-08-06 16:24:33 +02:00
qgroup.h btrfs: waiting on qgroup rescan should not always be interruptible 2016-09-07 08:32:43 +02:00
raid56.c Btrfs: make raid6 rebuild retry more 2018-07-03 11:21:24 +02:00
raid56.h
rcu-string.h
reada.c btrfs: reada: Fix returned errno code 2015-10-21 18:29:50 +02:00
relocation.c btrfs: relocation: Only remove reloc rb_trees if reloc control has been initialized 2018-09-15 09:40:40 +02:00
root-tree.c Btrfs: fix loading of orphan roots leading to BUG_ON 2016-03-09 15:34:53 -08:00
scrub.c btrfs: scrub: Don't use inode pages for device replace 2018-07-03 11:21:25 +02:00
send.c Btrfs: send, fix issuing write op when processing hole in no data mode 2018-05-30 07:49:03 +02:00
send.h
struct-funcs.c
super.c btrfs: resume qgroup rescan on rw remount 2017-09-13 14:09:46 -07:00
sysfs.c Btrfs: rename super_kobj to fsid_kobj 2015-09-29 16:29:59 +02:00
sysfs.h Btrfs: rename btrfs_kobj_rm_device to btrfs_sysfs_rm_device_link 2015-09-29 16:29:59 +02:00
transaction.c Btrfs: fix unprotected list move from unused_bgs to deleted_bgs list 2015-12-10 11:22:38 +00:00
transaction.h btrfs: account for non-CoW'd blocks in btrfs_abort_transaction 2016-07-27 09:47:33 -07:00
tree-defrag.c Btrfs: cleanup: remove unnecessary check before btrfs_free_path is called 2015-08-31 11:46:41 -07:00
tree-log.c btrfs: add barriers to btrfs_sync_log before log_commit_wait wakeups 2018-08-06 16:24:33 +02:00
tree-log.h
ulist.c
ulist.h
uuid-tree.c btrfs: return the actual error value from from btrfs_uuid_tree_iterate 2017-11-30 08:37:28 +00:00
volumes.c Btrfs: make raid6 rebuild retry more 2018-07-03 11:21:24 +02:00
volumes.h btrfs: fix clashing number of the enhanced balance usage filter 2015-11-25 05:19:50 -08:00
xattr.c Btrfs: fix race when listing an inode's xattrs 2015-11-09 18:34:40 +00:00
xattr.h
zlib.c