alistair23-linux/fs/btrfs
Qu Wenruo ae6529c35b btrfs: Wait for in-flight bios before freeing target device for raid56
When raid56 dev-replace is cancelled by running scrub, we will free
target device without waiting for in-flight bios, causing the following
NULL pointer deference or general protection failure.

 BUG: unable to handle kernel NULL pointer dereference at 00000000000005e0
 IP: generic_make_request_checks+0x4d/0x610
 CPU: 1 PID: 11676 Comm: kworker/u4:14 Tainted: G  O    4.11.0-rc2 #72
 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
 Workqueue: btrfs-endio-raid56 btrfs_endio_raid56_helper [btrfs]
 task: ffff88002875b4c0 task.stack: ffffc90001334000
 RIP: 0010:generic_make_request_checks+0x4d/0x610
 Call Trace:
  ? generic_make_request+0xc7/0x360
  generic_make_request+0x24/0x360
  ? generic_make_request+0xc7/0x360
  submit_bio+0x64/0x120
  ? page_in_rbio+0x4d/0x80 [btrfs]
  ? rbio_orig_end_io+0x80/0x80 [btrfs]
  finish_rmw+0x3f4/0x540 [btrfs]
  validate_rbio_for_rmw+0x36/0x40 [btrfs]
  raid_rmw_end_io+0x7a/0x90 [btrfs]
  bio_endio+0x56/0x60
  end_workqueue_fn+0x3c/0x40 [btrfs]
  btrfs_scrubparity_helper+0xef/0x620 [btrfs]
  btrfs_endio_raid56_helper+0xe/0x10 [btrfs]
  process_one_work+0x2af/0x720
  ? process_one_work+0x22b/0x720
  worker_thread+0x4b/0x4f0
  kthread+0x10f/0x150
  ? process_one_work+0x720/0x720
  ? kthread_create_on_node+0x40/0x40
  ret_from_fork+0x2e/0x40
 RIP: generic_make_request_checks+0x4d/0x610 RSP: ffffc90001337bb8

In btrfs_dev_replace_finishing(), we will call
btrfs_rm_dev_replace_blocked() to wait bios before destroying the target
device when scrub is finished normally.

However when dev-replace is aborted, either due to error or cancelled by
scrub, we didn't wait for bios, this can lead to use-after-free if there
are bios holding the target device.

Furthermore, for raid56 scrub, at least 2 places are calling
btrfs_map_sblock() without protection of bio_counter, leading to the
problem.

This patch fixes the problem:
1) Wait for bio_counter before freeing target device when canceling
   replace
2) When calling btrfs_map_sblock() for raid56, use bio_counter to
   protect the call.

Cc: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
2017-04-18 14:07:26 +02:00
..
tests btrfs: remove unused qgroup members from btrfs_trans_handle 2017-04-18 14:07:25 +02:00
acl.c posix_acl: Clear SGID bit when setting file permissions 2016-09-22 10:55:32 +02:00
async-thread.c btrfs: fix crash when tracepoint arguments are freed by wq callbacks 2017-01-09 11:24:50 +01:00
async-thread.h btrfs: limit async_work allocation and worker func duration 2016-12-13 11:01:30 -08:00
backref.c btrfs: replace hardcoded value with SEQ_LAST macro 2017-04-18 14:07:25 +02:00
backref.h btrfs: cleanup, remove inode_item_info helper 2015-01-14 19:23:47 +01:00
btrfs_inode.h btrfs: make btrfs_inode_resume_unlocked_dio take btrfs_inode 2017-02-28 11:30:12 +01:00
check-integrity.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
check-integrity.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
compression.c btrfs: convert compressed_bio.pending_bios from atomic_t to refcount_t 2017-04-18 14:07:24 +02:00
compression.h btrfs: derive maximum output size in the compression implementation 2017-02-28 14:26:36 +01:00
ctree.c btrfs: sink GFP flags parameter to tree_mod_log_insert_root 2017-04-18 14:07:26 +02:00
ctree.h btrfs: track exclusive filesystem operation in flags 2017-04-18 14:07:25 +02:00
dedupe.h btrfs: expand cow_file_range() to support in-band dedup and subpage-blocksize 2016-07-26 13:52:25 +02:00
delayed-inode.c btrfs: convert btrfs_delayed_item.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
delayed-inode.h btrfs: convert btrfs_delayed_item.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
delayed-ref.c btrfs: convert btrfs_delayed_ref_node.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
delayed-ref.h btrfs: convert btrfs_delayed_ref_node.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
dev-replace.c btrfs: Wait for in-flight bios before freeing target device for raid56 2017-04-18 14:07:26 +02:00
dev-replace.h btrfs: constify device path passed to relevant helpers 2017-02-28 14:26:07 +01:00
dir-item.c btrfs: do proper error handling in btrfs_insert_xattr_item 2017-02-28 14:27:11 +01:00
disk-io.c btrfs: remove redundant parameter from btree_readahead_hook 2017-04-18 14:07:25 +02:00
disk-io.h btrfs: convert btrfs_root.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
export.c btrfs: Make btrfs_ino take a struct btrfs_inode 2017-02-14 15:50:51 +01:00
export.h
extent-tree.c btrfs: remove unused qgroup members from btrfs_trans_handle 2017-04-18 14:07:25 +02:00
extent_io.c Btrfs: create a helper for getting chunk map 2017-04-18 14:07:24 +02:00
extent_io.h btrfs: convert extent_state.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
extent_map.c btrfs: convert extent_map.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
extent_map.h btrfs: convert extent_map.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
file-item.c Merge branch 'for-chris-4.11-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.11 2017-02-28 14:35:09 -08:00
file.c Merge branch 'for-linus-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs 2017-03-02 16:03:00 -08:00
free-space-cache.c Merge branch 'WIP.sched-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-03-03 10:16:38 -08:00
free-space-cache.h btrfs: free-space-cache, clean up unnecessary root arguments 2017-02-17 12:03:56 +01:00
free-space-tree.c btrfs: remove unused parameter from clean_tree_block 2017-02-17 12:03:51 +01:00
free-space-tree.h Btrfs: implement the free space B-tree 2015-12-17 12:16:47 -08:00
hash.c btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
hash.h btrfs: advertise which crc32c implementation is being used at module load 2016-06-06 14:08:28 +02:00
inode-item.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
inode-map.c btrfs: all btrfs_delalloc_release_metadata take btrfs_inode 2017-02-28 11:30:07 +01:00
inode-map.h Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots 2016-01-15 19:25:02 +01:00
inode.c Btrfs: add file item tracepoints 2017-04-18 14:07:24 +02:00
ioctl.c btrfs: track exclusive filesystem operation in flags 2017-04-18 14:07:25 +02:00
Kconfig rcu: Make SRCU optional by using CONFIG_SRCU 2015-01-06 11:04:29 -08:00
locking.c btrfs: cleanup, remove stray return statements 2016-01-07 14:30:52 +01:00
locking.h btrfs: fix lockups from btrfs_clear_path_blocking 2014-11-19 10:34:35 -08:00
lzo.c btrfs: derive maximum output size in the compression implementation 2017-02-28 14:26:36 +01:00
Makefile Btrfs: add free space tree sanity tests 2015-12-17 12:16:47 -08:00
math.h btrfs: cleanup 64bit/32bit divs, compile time constants 2015-03-03 17:23:57 +01:00
ordered-data.c btrfs: convert btrfs_ordered_extent.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
ordered-data.h btrfs: convert btrfs_ordered_extent.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
orphan.c btrfs: kill the key type accessor helpers 2014-09-17 13:37:12 -07:00
print-tree.c btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
print-tree.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
props.c btrfs: Make btrfs_ino take a struct btrfs_inode 2017-02-14 15:50:51 +01:00
props.h
qgroup.c btrfs: qgroup: Re-arrange tracepoint timing to co-operate with reserved space tracepoint 2017-04-18 14:07:26 +02:00
qgroup.h btrfs: qgroup: Re-arrange tracepoint timing to co-operate with reserved space tracepoint 2017-04-18 14:07:26 +02:00
raid56.c btrfs: Wait for in-flight bios before freeing target device for raid56 2017-04-18 14:07:26 +02:00
raid56.h btrfs: take an fs_info directly when the root is not used otherwise 2016-12-06 16:06:59 +01:00
rcu-string.h
reada.c btrfs: remove local blocksize variable in reada_find_extent 2017-04-18 14:07:25 +02:00
relocation.c btrfs: Make btrfs_orphan_add take btrfs_inode 2017-02-28 11:30:10 +01:00
root-tree.c Btrfs: constify struct btrfs_{,disk_}key wherever possible 2017-02-14 15:50:58 +01:00
scrub.c btrfs: Wait for in-flight bios before freeing target device for raid56 2017-04-18 14:07:26 +02:00
send.c Btrfs: fix an integer overflow check 2017-03-29 14:29:08 +02:00
send.h Btrfs: use linux/sizes.h to represent constants 2016-01-07 14:38:02 +01:00
struct-funcs.c btrfs: fix string and comment grammatical issues and typos 2016-05-25 22:35:14 +02:00
super.c btrfs: No need to check !(flags & MS_RDONLY) twice 2017-04-18 14:07:25 +02:00
sysfs.c btrfs: convert printk(KERN_* to use pr_* calls 2016-09-26 18:08:44 +02:00
sysfs.h btrfs: sysfs: introduce helper for syncing bits with sysfs files 2016-01-21 18:50:40 +01:00
transaction.c btrfs: remove unused qgroup members from btrfs_trans_handle 2017-04-18 14:07:25 +02:00
transaction.h btrfs: remove unused qgroup members from btrfs_trans_handle 2017-04-18 14:07:25 +02:00
tree-defrag.c Btrfs: fix locking bugs when defragging leaves 2015-12-18 02:51:32 +00:00
tree-log.c btrfs: convert extent_map.refs from atomic_t to refcount_t 2017-04-18 14:07:23 +02:00
tree-log.h btrfs: Make btrfs_del_inode_ref take btrfs_inode 2017-02-14 15:50:54 +01:00
ulist.c btrfs: ulist: rename ulist_fini to ulist_release 2017-02-17 12:03:50 +01:00
ulist.h btrfs: ulist: rename ulist_fini to ulist_release 2017-02-17 12:03:50 +01:00
uuid-tree.c btrfs: return the actual error value from from btrfs_uuid_tree_iterate 2016-12-19 18:08:15 +01:00
volumes.c btrfs: drop redundant parameters from btrfs_map_sblock 2017-04-18 14:07:26 +02:00
volumes.h btrfs: drop redundant parameters from btrfs_map_sblock 2017-04-18 14:07:26 +02:00
xattr.c btrfs: fix over-80 lines introduced by previous cleanups 2017-02-14 15:50:57 +01:00
xattr.h btrfs: Switch to generic xattr handlers 2016-05-17 19:17:09 -04:00
zlib.c btrfs: derive maximum output size in the compression implementation 2017-02-28 14:26:36 +01:00