linux-stable/fs/btrfs
Nikolay Borisov fb814f2150 btrfs: Ensure replaced device doesn't have pending chunk allocation
commit debd1c065d upstream.

Recent FITRIM work, namely bbbf7243d6 ("btrfs: combine device update
operations during transaction commit") combined the way certain
operations are recoded in a transaction. As a result an ASSERT was added
in dev_replace_finish to ensure the new code works correctly.
Unfortunately I got reports that it's possible to trigger the assert,
meaning that during a device replace it's possible to have an unfinished
chunk allocation on the source device.

This is supposed to be prevented by the fact that a transaction is
committed before finishing the replace oepration and alter acquiring the
chunk mutex. This is not sufficient since by the time the transaction is
committed and the chunk mutex acquired it's possible to allocate a chunk
depending on the workload being executed on the replaced device. This
bug has been present ever since device replace was introduced but there
was never code which checks for it.

The correct way to fix is to ensure that there is no pending device
modification operation when the chunk mutex is acquire and if there is
repeat transaction commit. Unfortunately it's not possible to just
exclude the source device from btrfs_fs_devices::dev_alloc_list since
this causes ENOSPC to be hit in transaction commit.

Fixing that in another way would need to add special cases to handle the
last writes and forbid new ones. The looped transaction fix is more
obvious, and can be easily backported. The runtime of dev-replace is
long so there's no noticeable delay caused by that.

Reported-by: David Sterba <dsterba@suse.com>
Fixes: 391cd9df81 ("Btrfs: fix unprotected alloc list insertion during the finishing procedure of replace")
CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-07-10 09:53:44 +02:00
..
tests btrfs: qgroup: Drop fs_info parameter from btrfs_qgroup_account_extent 2018-08-06 13:12:52 +02:00
acl.c Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl 2019-03-23 20:10:00 +01:00
async-thread.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
async-thread.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
backref.c btrfs: honor path->skip_locking in backref code 2019-05-31 06:46:03 -07:00
backref.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
btrfs_inode.h btrfs: use tagged writepage to mitigate livelock of snapshot 2019-02-12 19:47:11 +01:00
check-integrity.c btrfs: open-code bio_set_op_attrs 2018-08-06 13:12:44 +02:00
check-integrity.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
compression.c btrfs: drop extent_io_ops::merge_bio_hook callback 2018-08-06 13:12:56 +02:00
compression.h btrfs: compression: Add linux/sizes.h for compression.h 2018-05-29 18:13:00 +02:00
ctree.c btrfs: Check the first key and level for cached extent buffer 2019-05-22 07:37:42 +02:00
ctree.h btrfs: use tagged writepage to mitigate livelock of snapshot 2019-02-12 19:47:11 +01:00
dedupe.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
delayed-inode.c btrfs: Remove fs_info from btrfs_delete_delayed_dir_index 2018-08-06 13:13:00 +02:00
delayed-inode.h btrfs: Remove fs_info from btrfs_delete_delayed_dir_index 2018-08-06 13:13:00 +02:00
delayed-ref.c btrfs: Streamline memory allocation failure handling in btrfs_add_delayed_tree_ref 2018-08-06 13:12:39 +02:00
delayed-ref.h btrfs: Remove fs_info from btrfs_add_delayed_data_ref 2018-08-06 13:12:34 +02:00
dev-replace.c btrfs: Ensure replaced device doesn't have pending chunk allocation 2019-07-10 09:53:44 +02:00
dev-replace.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
dir-item.c btrfs: Remove fs_info from btrfs_insert_delayed_dir_index 2018-08-06 13:13:00 +02:00
disk-io.c btrfs: Correctly free extent buffer in case btree_read_extent_buffer_pages fails 2019-05-22 07:37:42 +02:00
disk-io.h btrfs: Check the first key and level for cached extent buffer 2019-05-22 07:37:42 +02:00
export.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
export.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
extent-tree.c Revert "btrfs: Honour FITRIM range constraints during free space trim" 2019-05-31 06:46:05 -07:00
extent_io.c Btrfs: fix corruption reading shared and compressed extents after hole punching 2019-03-23 20:10:00 +01:00
extent_io.h btrfs: drop extent_io_ops::set_range_writeback callback 2018-08-06 13:12:56 +02:00
extent_map.c btrfs: use fs_info for btrfs_handle_em_exist tracepoint 2018-05-28 18:07:17 +02:00
extent_map.h btrfs: use fs_info for btrfs_handle_em_exist tracepoint 2018-05-28 18:07:17 +02:00
file-item.c btrfs: simplify pointer chasing of local fs_info variables 2018-08-06 13:12:43 +02:00
file.c Btrfs: fix data bytes_may_use underflow with fallocate due to failed quota reserve 2019-05-31 06:46:13 -07:00
free-space-cache.c Btrfs: fix use-after-free when dumping free space 2018-11-13 11:09:00 -08:00
free-space-cache.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
free-space-tree.c btrfs: Remove fs_info from btrfs_del_root 2018-08-06 13:13:00 +02:00
free-space-tree.h btrfs: Remove fs_info argument from add_to_free_space_tree 2018-05-28 18:07:36 +02:00
inode-item.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
inode-map.c btrfs: prune unused includes 2018-08-06 13:12:43 +02:00
inode-map.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
inode.c Btrfs: fix wrong ctime and mtime of a directory after log replay 2019-06-09 09:17:14 +02:00
ioctl.c Btrfs: do not allow trimming when a fs is mounted with the nologreplay option 2019-04-17 08:38:51 +02:00
Kconfig btrfs: add SPDX header to Kconfig 2018-04-12 16:29:55 +02:00
locking.c btrfs: replace waitqueue_actvie with cond_wake_up 2018-05-28 18:23:09 +02:00
locking.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
lzo.c btrfs: lzo: Harden inline lzo compressed extent decompression 2018-05-30 16:46:43 +02:00
Makefile btrfs: Remove custom crc32c init code 2018-03-26 15:09:39 +02:00
math.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
ordered-data.c btrfs: prune unused includes 2018-08-06 13:12:43 +02:00
ordered-data.h btrfs: remove remaing full_sync logic from btrfs_sync_file 2018-08-06 13:12:31 +02:00
orphan.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
print-tree.c btrfs: annotate unlikely branches after V0 extent type removal 2018-08-06 13:12:41 +02:00
print-tree.h btrfs: print-tree: debugging output enhancement 2018-04-20 19:18:16 +02:00
props.c btrfs: prop: fix vanished compression property after failed set 2019-04-17 08:38:51 +02:00
props.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
qgroup.c btrfs: qgroup: Make qgroup async transaction commit more aggressive 2019-04-05 22:33:02 +02:00
qgroup.h btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled 2018-11-13 11:08:56 -08:00
raid56.c btrfs: raid56: properly unmap parity page in finish_parity_scrub() 2019-04-03 06:26:21 +02:00
raid56.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
rcu-string.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
reada.c btrfs: start readahead also in seed devices 2019-06-25 11:35:59 +08:00
ref-verify.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
ref-verify.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
relocation.c btrfs: fix panic during relocation after ENOSPC before writeback happens 2019-05-31 06:46:13 -07:00
root-tree.c btrfs: Don't panic when we can't find a root key 2019-05-31 06:46:13 -07:00
scrub.c btrfs: Use wrapper macro for rcu string to remove duplicate code 2018-08-06 13:13:02 +02:00
send.c Btrfs: incremental send, fix file corruption when no-holes feature is enabled 2019-06-09 09:17:15 +02:00
send.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
struct-funcs.c btrfs: prune unused includes 2018-08-06 13:12:43 +02:00
super.c btrfs: On error always free subvol_name in btrfs_mount 2019-02-06 17:30:14 +01:00
sysfs.c btrfs: sysfs: don't leak memory when failing add fsid 2019-05-31 06:46:02 -07:00
sysfs.h btrfs: sysfs: Use enum/define value for feature array definitions 2018-05-28 18:23:39 +02:00
transaction.c btrfs: don't run delayed_iputs in commit 2018-11-13 11:08:59 -08:00
transaction.h btrfs: replace get_seconds with new 64bit time API 2018-08-06 13:12:29 +02:00
tree-checker.c btrfs: tree-checker: Don't check max block group size as current max chunk size limit is unreliable 2018-12-08 12:59:10 +01:00
tree-checker.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
tree-defrag.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
tree-log.c Btrfs: fix fsync not persisting changed attributes of a directory 2019-06-09 09:17:14 +02:00
tree-log.h Btrfs: sync log after logging new name 2018-08-23 17:37:26 +02:00
ulist.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
ulist.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
uuid-tree.c btrfs: Remove fs_info argument from btrfs_uuid_tree_rem 2018-05-30 16:46:53 +02:00
volumes.c btrfs: Ensure replaced device doesn't have pending chunk allocation 2019-07-10 09:53:44 +02:00
volumes.h btrfs: Ensure replaced device doesn't have pending chunk allocation 2019-07-10 09:53:44 +02:00
xattr.c Btrfs: use nofs context when initializing security xattrs to avoid deadlock 2019-01-16 22:04:37 +01:00
xattr.h btrfs: replace GPL boilerplate by SPDX -- headers 2018-04-12 16:29:46 +02:00
zlib.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00
zstd.c btrfs: replace GPL boilerplate by SPDX -- sources 2018-04-12 16:29:51 +02:00