@@ -762,36 +762,40 @@ static noinline struct btrfs_device *device_list_add(const char *path,
762
762
if (IS_ERR (fs_devices ))
763
763
return ERR_CAST (fs_devices );
764
764
765
+ mutex_lock (& fs_devices -> device_list_mutex );
765
766
list_add (& fs_devices -> fs_list , & fs_uuids );
766
767
767
768
device = NULL ;
768
769
} else {
770
+ mutex_lock (& fs_devices -> device_list_mutex );
769
771
device = find_device (fs_devices , devid ,
770
772
disk_super -> dev_item .uuid );
771
773
}
772
774
773
775
if (!device ) {
774
- if (fs_devices -> opened )
776
+ if (fs_devices -> opened ) {
777
+ mutex_unlock (& fs_devices -> device_list_mutex );
775
778
return ERR_PTR (- EBUSY );
779
+ }
776
780
777
781
device = btrfs_alloc_device (NULL , & devid ,
778
782
disk_super -> dev_item .uuid );
779
783
if (IS_ERR (device )) {
784
+ mutex_unlock (& fs_devices -> device_list_mutex );
780
785
/* we can safely leave the fs_devices entry around */
781
786
return device ;
782
787
}
783
788
784
789
name = rcu_string_strdup (path , GFP_NOFS );
785
790
if (!name ) {
786
791
btrfs_free_device (device );
792
+ mutex_unlock (& fs_devices -> device_list_mutex );
787
793
return ERR_PTR (- ENOMEM );
788
794
}
789
795
rcu_assign_pointer (device -> name , name );
790
796
791
- mutex_lock (& fs_devices -> device_list_mutex );
792
797
list_add_rcu (& device -> dev_list , & fs_devices -> devices );
793
798
fs_devices -> num_devices ++ ;
794
- mutex_unlock (& fs_devices -> device_list_mutex );
795
799
796
800
device -> fs_devices = fs_devices ;
797
801
* new_device_added = true;
@@ -838,12 +842,15 @@ static noinline struct btrfs_device *device_list_add(const char *path,
838
842
* with larger generation number or the last-in if
839
843
* generation are equal.
840
844
*/
845
+ mutex_unlock (& fs_devices -> device_list_mutex );
841
846
return ERR_PTR (- EEXIST );
842
847
}
843
848
844
849
name = rcu_string_strdup (path , GFP_NOFS );
845
- if (!name )
850
+ if (!name ) {
851
+ mutex_unlock (& fs_devices -> device_list_mutex );
846
852
return ERR_PTR (- ENOMEM );
853
+ }
847
854
rcu_string_free (device -> name );
848
855
rcu_assign_pointer (device -> name , name );
849
856
if (test_bit (BTRFS_DEV_STATE_MISSING , & device -> dev_state )) {
@@ -863,6 +870,7 @@ static noinline struct btrfs_device *device_list_add(const char *path,
863
870
864
871
fs_devices -> total_devices = btrfs_super_num_devices (disk_super );
865
872
873
+ mutex_unlock (& fs_devices -> device_list_mutex );
866
874
return device ;
867
875
}
868
876
0 commit comments