Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-5.9-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
"Two more fixes.

One is for a lockdep warning/lockup (also caught by syzbot), that one
has been seen in practice. Regarding the other syzbot reports
mentioned last time, they don't seem to be urgent and reliably
reproducible so they'll be fixed later.

The second fix is for a potential corruption when device replace
finishes and the in-memory state of trim is not copied to the new
device"

* tag 'for-5.9-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
btrfs: fix filesystem corruption after a device replace
btrfs: move btrfs_rm_dev_replace_free_srcdev outside of all locks
btrfs: move btrfs_scratch_superblocks into btrfs_dev_replace_finishing

+52 -10
+44 -2
fs/btrfs/dev-replace.c
··· 599 599 wake_up(&fs_info->dev_replace.replace_wait); 600 600 } 601 601 602 + /* 603 + * When finishing the device replace, before swapping the source device with the 604 + * target device we must update the chunk allocation state in the target device, 605 + * as it is empty because replace works by directly copying the chunks and not 606 + * through the normal chunk allocation path. 607 + */ 608 + static int btrfs_set_target_alloc_state(struct btrfs_device *srcdev, 609 + struct btrfs_device *tgtdev) 610 + { 611 + struct extent_state *cached_state = NULL; 612 + u64 start = 0; 613 + u64 found_start; 614 + u64 found_end; 615 + int ret = 0; 616 + 617 + lockdep_assert_held(&srcdev->fs_info->chunk_mutex); 618 + 619 + while (!find_first_extent_bit(&srcdev->alloc_state, start, 620 + &found_start, &found_end, 621 + CHUNK_ALLOCATED, &cached_state)) { 622 + ret = set_extent_bits(&tgtdev->alloc_state, found_start, 623 + found_end, CHUNK_ALLOCATED); 624 + if (ret) 625 + break; 626 + start = found_end + 1; 627 + } 628 + 629 + free_extent_state(cached_state); 630 + return ret; 631 + } 632 + 602 633 static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, 603 634 int scrub_ret) 604 635 { ··· 704 673 dev_replace->time_stopped = ktime_get_real_seconds(); 705 674 dev_replace->item_needs_writeback = 1; 706 675 707 - /* replace old device with new one in mapping tree */ 676 + /* 677 + * Update allocation state in the new device and replace the old device 678 + * with the new one in the mapping tree. 679 + */ 708 680 if (!scrub_ret) { 681 + scrub_ret = btrfs_set_target_alloc_state(src_device, tgt_device); 682 + if (scrub_ret) 683 + goto error; 709 684 btrfs_dev_replace_update_device_in_mapping_tree(fs_info, 710 685 src_device, 711 686 tgt_device); ··· 722 685 btrfs_dev_name(src_device), 723 686 src_device->devid, 724 687 rcu_str_deref(tgt_device->name), scrub_ret); 688 + error: 725 689 up_write(&dev_replace->rwsem); 726 690 mutex_unlock(&fs_info->chunk_mutex); 727 691 mutex_unlock(&fs_info->fs_devices->device_list_mutex); ··· 783 745 /* replace the sysfs entry */ 784 746 btrfs_sysfs_remove_devices_dir(fs_info->fs_devices, src_device); 785 747 btrfs_sysfs_update_devid(tgt_device); 786 - btrfs_rm_dev_replace_free_srcdev(src_device); 748 + if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &src_device->dev_state)) 749 + btrfs_scratch_superblocks(fs_info, src_device->bdev, 750 + src_device->name->str); 787 751 788 752 /* write back the superblocks */ 789 753 trans = btrfs_start_transaction(root, 0); ··· 793 753 btrfs_commit_transaction(trans); 794 754 795 755 mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); 756 + 757 + btrfs_rm_dev_replace_free_srcdev(src_device); 796 758 797 759 return 0; 798 760 }
+5 -8
fs/btrfs/volumes.c
··· 1999 1999 return num_devices; 2000 2000 } 2001 2001 2002 - static void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info, 2003 - struct block_device *bdev, 2004 - const char *device_path) 2002 + void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info, 2003 + struct block_device *bdev, 2004 + const char *device_path) 2005 2005 { 2006 2006 struct btrfs_super_block *disk_super; 2007 2007 int copy_num; ··· 2224 2224 struct btrfs_fs_info *fs_info = srcdev->fs_info; 2225 2225 struct btrfs_fs_devices *fs_devices = srcdev->fs_devices; 2226 2226 2227 - if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &srcdev->dev_state)) { 2228 - /* zero out the old super if it is writable */ 2229 - btrfs_scratch_superblocks(fs_info, srcdev->bdev, 2230 - srcdev->name->str); 2231 - } 2227 + mutex_lock(&uuid_mutex); 2232 2228 2233 2229 btrfs_close_bdev(srcdev); 2234 2230 synchronize_rcu(); ··· 2254 2258 close_fs_devices(fs_devices); 2255 2259 free_fs_devices(fs_devices); 2256 2260 } 2261 + mutex_unlock(&uuid_mutex); 2257 2262 } 2258 2263 2259 2264 void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev)
+3
fs/btrfs/volumes.h
··· 573 573 void btrfs_reset_fs_info_ptr(struct btrfs_fs_info *fs_info); 574 574 bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info, 575 575 struct btrfs_device *failing_dev); 576 + void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info, 577 + struct block_device *bdev, 578 + const char *device_path); 576 579 577 580 int btrfs_bg_type_to_factor(u64 flags); 578 581 const char *btrfs_bg_type_to_raid_name(u64 flags);