@@ -1752,13 +1752,11 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1752
1752
{
1753
1753
struct btrfs_device * device ;
1754
1754
struct btrfs_device * next_device ;
1755
- struct block_device * bdev ;
1755
+ struct block_device * bdev = NULL ;
1756
1756
struct buffer_head * bh = NULL ;
1757
- struct btrfs_super_block * disk_super ;
1757
+ struct btrfs_super_block * disk_super = NULL ;
1758
1758
struct btrfs_fs_devices * cur_devices ;
1759
- u64 devid ;
1760
1759
u64 num_devices ;
1761
- u8 * dev_uuid ;
1762
1760
int ret = 0 ;
1763
1761
bool clear_super = false;
1764
1762
@@ -1768,57 +1766,19 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1768
1766
if (ret )
1769
1767
goto out ;
1770
1768
1771
- if (strcmp (device_path , "missing" ) == 0 ) {
1772
- struct list_head * devices ;
1773
- struct btrfs_device * tmp ;
1774
-
1775
- device = NULL ;
1776
- devices = & root -> fs_info -> fs_devices -> devices ;
1777
- /*
1778
- * It is safe to read the devices since the volume_mutex
1779
- * is held.
1780
- */
1781
- list_for_each_entry (tmp , devices , dev_list ) {
1782
- if (tmp -> in_fs_metadata &&
1783
- !tmp -> is_tgtdev_for_dev_replace &&
1784
- !tmp -> bdev ) {
1785
- device = tmp ;
1786
- break ;
1787
- }
1788
- }
1789
- bdev = NULL ;
1790
- bh = NULL ;
1791
- disk_super = NULL ;
1792
- if (!device ) {
1793
- ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND ;
1794
- goto out ;
1795
- }
1796
- } else {
1797
- ret = btrfs_get_bdev_and_sb (device_path ,
1798
- FMODE_WRITE | FMODE_EXCL ,
1799
- root -> fs_info -> bdev_holder , 0 ,
1800
- & bdev , & bh );
1801
- if (ret )
1802
- goto out ;
1803
- disk_super = (struct btrfs_super_block * )bh -> b_data ;
1804
- devid = btrfs_stack_device_id (& disk_super -> dev_item );
1805
- dev_uuid = disk_super -> dev_item .uuid ;
1806
- device = btrfs_find_device (root -> fs_info , devid , dev_uuid ,
1807
- disk_super -> fsid );
1808
- if (!device ) {
1809
- ret = - ENOENT ;
1810
- goto error_brelse ;
1811
- }
1812
- }
1769
+ ret = btrfs_find_device_by_user_input (root , 0 , device_path ,
1770
+ & device );
1771
+ if (ret )
1772
+ goto out ;
1813
1773
1814
1774
if (device -> is_tgtdev_for_dev_replace ) {
1815
1775
ret = BTRFS_ERROR_DEV_TGT_REPLACE ;
1816
- goto error_brelse ;
1776
+ goto out ;
1817
1777
}
1818
1778
1819
1779
if (device -> writeable && root -> fs_info -> fs_devices -> rw_devices == 1 ) {
1820
1780
ret = BTRFS_ERROR_DEV_ONLY_WRITABLE ;
1821
- goto error_brelse ;
1781
+ goto out ;
1822
1782
}
1823
1783
1824
1784
if (device -> writeable ) {
@@ -1908,16 +1868,33 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1908
1868
* at this point, the device is zero sized. We want to
1909
1869
* remove it from the devices list and zero out the old super
1910
1870
*/
1911
- if (clear_super && disk_super ) {
1871
+ if (clear_super ) {
1912
1872
u64 bytenr ;
1913
1873
int i ;
1914
1874
1875
+ if (!disk_super ) {
1876
+ ret = btrfs_get_bdev_and_sb (device_path ,
1877
+ FMODE_WRITE | FMODE_EXCL ,
1878
+ root -> fs_info -> bdev_holder , 0 ,
1879
+ & bdev , & bh );
1880
+ if (ret ) {
1881
+ /*
1882
+ * It could be a failed device ok for clear_super
1883
+ * to fail. So return success
1884
+ */
1885
+ ret = 0 ;
1886
+ goto out ;
1887
+ }
1888
+
1889
+ disk_super = (struct btrfs_super_block * )bh -> b_data ;
1890
+ }
1915
1891
/* make sure this device isn't detected as part of
1916
1892
* the FS anymore
1917
1893
*/
1918
1894
memset (& disk_super -> magic , 0 , sizeof (disk_super -> magic ));
1919
1895
set_buffer_dirty (bh );
1920
1896
sync_dirty_buffer (bh );
1897
+ brelse (bh );
1921
1898
1922
1899
/* clear the mirror copies of super block on the disk
1923
1900
* being removed, 0th copy is been taken care above and
@@ -1929,7 +1906,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1929
1906
i_size_read (bdev -> bd_inode ))
1930
1907
break ;
1931
1908
1932
- brelse (bh );
1933
1909
bh = __bread (bdev , bytenr / 4096 ,
1934
1910
BTRFS_SUPER_INFO_SIZE );
1935
1911
if (!bh )
@@ -1939,32 +1915,30 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1939
1915
1940
1916
if (btrfs_super_bytenr (disk_super ) != bytenr ||
1941
1917
btrfs_super_magic (disk_super ) != BTRFS_MAGIC ) {
1918
+ brelse (bh );
1942
1919
continue ;
1943
1920
}
1944
1921
memset (& disk_super -> magic , 0 ,
1945
1922
sizeof (disk_super -> magic ));
1946
1923
set_buffer_dirty (bh );
1947
1924
sync_dirty_buffer (bh );
1925
+ brelse (bh );
1948
1926
}
1949
- }
1950
1927
1951
- ret = 0 ;
1952
-
1953
- if (bdev ) {
1954
- /* Notify udev that device has changed */
1955
- btrfs_kobject_uevent (bdev , KOBJ_CHANGE );
1928
+ if (bdev ) {
1929
+ /* Notify udev that device has changed */
1930
+ btrfs_kobject_uevent (bdev , KOBJ_CHANGE );
1956
1931
1957
- /* Update ctime/mtime for device path for libblkid */
1958
- update_dev_time (device_path );
1932
+ /* Update ctime/mtime for device path for libblkid */
1933
+ update_dev_time (device_path );
1934
+ blkdev_put (bdev , FMODE_READ | FMODE_EXCL );
1935
+ }
1959
1936
}
1960
1937
1961
- error_brelse :
1962
- brelse (bh );
1963
- if (bdev )
1964
- blkdev_put (bdev , FMODE_READ | FMODE_EXCL );
1965
1938
out :
1966
1939
mutex_unlock (& uuid_mutex );
1967
1940
return ret ;
1941
+
1968
1942
error_undo :
1969
1943
if (device -> writeable ) {
1970
1944
lock_chunks (root );
@@ -1973,7 +1947,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
1973
1947
device -> fs_devices -> rw_devices ++ ;
1974
1948
unlock_chunks (root );
1975
1949
}
1976
- goto error_brelse ;
1950
+ goto out ;
1977
1951
}
1978
1952
1979
1953
void btrfs_rm_dev_replace_remove_srcdev (struct btrfs_fs_info * fs_info ,
0 commit comments