@@ -1756,10 +1756,49 @@ static int btrfs_check_raid_min_devices(struct btrfs_fs_info *fs_info,
1756
1756
return 0 ;
1757
1757
}
1758
1758
1759
+ struct btrfs_device * btrfs_find_next_active_device (struct btrfs_fs_devices * fs_devs ,
1760
+ struct btrfs_device * device )
1761
+ {
1762
+ struct btrfs_device * next_device ;
1763
+
1764
+ list_for_each_entry (next_device , & fs_devs -> devices , dev_list ) {
1765
+ if (next_device != device &&
1766
+ !next_device -> missing && next_device -> bdev )
1767
+ return next_device ;
1768
+ }
1769
+
1770
+ return NULL ;
1771
+ }
1772
+
1773
+ /*
1774
+ * Helper function to check if the given device is part of s_bdev / latest_bdev
1775
+ * and replace it with the provided or the next active device, in the context
1776
+ * where this function called, there should be always be another device (or
1777
+ * this_dev) which is active.
1778
+ */
1779
+ void btrfs_assign_next_active_device (struct btrfs_fs_info * fs_info ,
1780
+ struct btrfs_device * device , struct btrfs_device * this_dev )
1781
+ {
1782
+ struct btrfs_device * next_device ;
1783
+
1784
+ if (this_dev )
1785
+ next_device = this_dev ;
1786
+ else
1787
+ next_device = btrfs_find_next_active_device (fs_info -> fs_devices ,
1788
+ device );
1789
+ ASSERT (next_device );
1790
+
1791
+ if (fs_info -> sb -> s_bdev &&
1792
+ (fs_info -> sb -> s_bdev == device -> bdev ))
1793
+ fs_info -> sb -> s_bdev = next_device -> bdev ;
1794
+
1795
+ if (fs_info -> fs_devices -> latest_bdev == device -> bdev )
1796
+ fs_info -> fs_devices -> latest_bdev = next_device -> bdev ;
1797
+ }
1798
+
1759
1799
int btrfs_rm_device (struct btrfs_root * root , char * device_path , u64 devid )
1760
1800
{
1761
1801
struct btrfs_device * device ;
1762
- struct btrfs_device * next_device ;
1763
1802
struct btrfs_fs_devices * cur_devices ;
1764
1803
u64 num_devices ;
1765
1804
int ret = 0 ;
@@ -1846,13 +1885,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
1846
1885
if (device -> missing )
1847
1886
device -> fs_devices -> missing_devices -- ;
1848
1887
1849
- next_device = list_entry (root -> fs_info -> fs_devices -> devices .next ,
1850
- struct btrfs_device , dev_list );
1851
- if (root -> fs_info -> sb -> s_bdev &&
1852
- (root -> fs_info -> sb -> s_bdev == device -> bdev ))
1853
- root -> fs_info -> sb -> s_bdev = next_device -> bdev ;
1854
- if (device -> bdev == root -> fs_info -> fs_devices -> latest_bdev )
1855
- root -> fs_info -> fs_devices -> latest_bdev = next_device -> bdev ;
1888
+ btrfs_assign_next_active_device (root -> fs_info , device , NULL );
1856
1889
1857
1890
if (device -> bdev ) {
1858
1891
device -> fs_devices -> open_devices -- ;
@@ -1981,8 +2014,6 @@ void btrfs_rm_dev_replace_free_srcdev(struct btrfs_fs_info *fs_info,
1981
2014
void btrfs_destroy_dev_replace_tgtdev (struct btrfs_fs_info * fs_info ,
1982
2015
struct btrfs_device * tgtdev )
1983
2016
{
1984
- struct btrfs_device * next_device ;
1985
-
1986
2017
mutex_lock (& uuid_mutex );
1987
2018
WARN_ON (!tgtdev );
1988
2019
mutex_lock (& fs_info -> fs_devices -> device_list_mutex );
@@ -1995,13 +2026,8 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
1995
2026
}
1996
2027
fs_info -> fs_devices -> num_devices -- ;
1997
2028
1998
- next_device = list_entry (fs_info -> fs_devices -> devices .next ,
1999
- struct btrfs_device , dev_list );
2000
- if (fs_info -> sb -> s_bdev &&
2001
- (tgtdev -> bdev == fs_info -> sb -> s_bdev ))
2002
- fs_info -> sb -> s_bdev = next_device -> bdev ;
2003
- if (tgtdev -> bdev == fs_info -> fs_devices -> latest_bdev )
2004
- fs_info -> fs_devices -> latest_bdev = next_device -> bdev ;
2029
+ btrfs_assign_next_active_device (fs_info , tgtdev , NULL );
2030
+
2005
2031
list_del_rcu (& tgtdev -> dev_list );
2006
2032
2007
2033
call_rcu (& tgtdev -> rcu , free_device );
0 commit comments