@@ -319,7 +319,6 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid,
319
319
mutex_init (& fs_devs -> device_list_mutex );
320
320
321
321
INIT_LIST_HEAD (& fs_devs -> devices );
322
- INIT_LIST_HEAD (& fs_devs -> resized_devices );
323
322
INIT_LIST_HEAD (& fs_devs -> alloc_list );
324
323
INIT_LIST_HEAD (& fs_devs -> fs_list );
325
324
if (fsid )
@@ -335,6 +334,7 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid,
335
334
336
335
void btrfs_free_device (struct btrfs_device * device )
337
336
{
337
+ WARN_ON (!list_empty (& device -> post_commit_list ));
338
338
rcu_string_free (device -> name );
339
339
bio_put (device -> flush_bio );
340
340
kfree (device );
@@ -403,7 +403,7 @@ static struct btrfs_device *__alloc_device(void)
403
403
404
404
INIT_LIST_HEAD (& dev -> dev_list );
405
405
INIT_LIST_HEAD (& dev -> dev_alloc_list );
406
- INIT_LIST_HEAD (& dev -> resized_list );
406
+ INIT_LIST_HEAD (& dev -> post_commit_list );
407
407
408
408
spin_lock_init (& dev -> io_lock );
409
409
@@ -2853,7 +2853,6 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
2853
2853
{
2854
2854
struct btrfs_fs_info * fs_info = device -> fs_info ;
2855
2855
struct btrfs_super_block * super_copy = fs_info -> super_copy ;
2856
- struct btrfs_fs_devices * fs_devices ;
2857
2856
u64 old_total ;
2858
2857
u64 diff ;
2859
2858
@@ -2872,18 +2871,16 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
2872
2871
return - EINVAL ;
2873
2872
}
2874
2873
2875
- fs_devices = fs_info -> fs_devices ;
2876
-
2877
2874
btrfs_set_super_total_bytes (super_copy ,
2878
2875
round_down (old_total + diff , fs_info -> sectorsize ));
2879
2876
device -> fs_devices -> total_rw_bytes += diff ;
2880
2877
2881
2878
btrfs_device_set_total_bytes (device , new_size );
2882
2879
btrfs_device_set_disk_total_bytes (device , new_size );
2883
2880
btrfs_clear_space_info_full (device -> fs_info );
2884
- if (list_empty (& device -> resized_list ))
2885
- list_add_tail (& device -> resized_list ,
2886
- & fs_devices -> resized_devices );
2881
+ if (list_empty (& device -> post_commit_list ))
2882
+ list_add_tail (& device -> post_commit_list ,
2883
+ & trans -> transaction -> dev_update_list );
2887
2884
mutex_unlock (& fs_info -> chunk_mutex );
2888
2885
2889
2886
return btrfs_update_device (trans , device );
@@ -4872,9 +4869,9 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
4872
4869
}
4873
4870
4874
4871
btrfs_device_set_disk_total_bytes (device , new_size );
4875
- if (list_empty (& device -> resized_list ))
4876
- list_add_tail (& device -> resized_list ,
4877
- & fs_info -> fs_devices -> resized_devices );
4872
+ if (list_empty (& device -> post_commit_list ))
4873
+ list_add_tail (& device -> post_commit_list ,
4874
+ & trans -> transaction -> dev_update_list );
4878
4875
4879
4876
WARN_ON (diff > old_total );
4880
4877
btrfs_set_super_total_bytes (super_copy ,
@@ -5214,9 +5211,14 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
5214
5211
if (ret )
5215
5212
goto error_del_extent ;
5216
5213
5217
- for (i = 0 ; i < map -> num_stripes ; i ++ )
5218
- btrfs_device_set_bytes_used (map -> stripes [i ].dev ,
5219
- map -> stripes [i ].dev -> bytes_used + stripe_size );
5214
+ for (i = 0 ; i < map -> num_stripes ; i ++ ) {
5215
+ struct btrfs_device * dev = map -> stripes [i ].dev ;
5216
+
5217
+ btrfs_device_set_bytes_used (dev , dev -> bytes_used + stripe_size );
5218
+ if (list_empty (& dev -> post_commit_list ))
5219
+ list_add_tail (& dev -> post_commit_list ,
5220
+ & trans -> transaction -> dev_update_list );
5221
+ }
5220
5222
5221
5223
atomic64_sub (stripe_size * map -> num_stripes , & info -> free_chunk_space );
5222
5224
@@ -7579,51 +7581,34 @@ void btrfs_scratch_superblocks(struct block_device *bdev, const char *device_pat
7579
7581
}
7580
7582
7581
7583
/*
7582
- * Update the size of all devices, which is used for writing out the
7583
- * super blocks.
7584
+ * Update the size and bytes used for each device where it changed. This is
7585
+ * delayed since we would otherwise get errors while writing out the
7586
+ * superblocks.
7587
+ *
7588
+ * Must be invoked during transaction commit.
7584
7589
*/
7585
- void btrfs_update_commit_device_size (struct btrfs_fs_info * fs_info )
7590
+ void btrfs_commit_device_sizes (struct btrfs_transaction * trans )
7586
7591
{
7587
- struct btrfs_fs_devices * fs_devices = fs_info -> fs_devices ;
7588
7592
struct btrfs_device * curr , * next ;
7589
7593
7590
- if (list_empty (& fs_devices -> resized_devices ))
7591
- return ;
7592
-
7593
- mutex_lock (& fs_devices -> device_list_mutex );
7594
- mutex_lock (& fs_info -> chunk_mutex );
7595
- list_for_each_entry_safe (curr , next , & fs_devices -> resized_devices ,
7596
- resized_list ) {
7597
- list_del_init (& curr -> resized_list );
7598
- curr -> commit_total_bytes = curr -> disk_total_bytes ;
7599
- }
7600
- mutex_unlock (& fs_info -> chunk_mutex );
7601
- mutex_unlock (& fs_devices -> device_list_mutex );
7602
- }
7603
-
7604
- /* Must be invoked during the transaction commit */
7605
- void btrfs_update_commit_device_bytes_used (struct btrfs_transaction * trans )
7606
- {
7607
- struct btrfs_fs_info * fs_info = trans -> fs_info ;
7608
- struct extent_map * em ;
7609
- struct map_lookup * map ;
7610
- struct btrfs_device * dev ;
7611
- int i ;
7594
+ ASSERT (trans -> state == TRANS_STATE_COMMIT_DOING );
7612
7595
7613
- if (list_empty (& trans -> pending_chunks ))
7596
+ if (list_empty (& trans -> dev_update_list ))
7614
7597
return ;
7615
7598
7616
- /* In order to kick the device replace finish process */
7617
- mutex_lock (& fs_info -> chunk_mutex );
7618
- list_for_each_entry (em , & trans -> pending_chunks , list ) {
7619
- map = em -> map_lookup ;
7620
-
7621
- for (i = 0 ; i < map -> num_stripes ; i ++ ) {
7622
- dev = map -> stripes [i ].dev ;
7623
- dev -> commit_bytes_used = dev -> bytes_used ;
7624
- }
7599
+ /*
7600
+ * We don't need the device_list_mutex here. This list is owned by the
7601
+ * transaction and the transaction must complete before the device is
7602
+ * released.
7603
+ */
7604
+ mutex_lock (& trans -> fs_info -> chunk_mutex );
7605
+ list_for_each_entry_safe (curr , next , & trans -> dev_update_list ,
7606
+ post_commit_list ) {
7607
+ list_del_init (& curr -> post_commit_list );
7608
+ curr -> commit_total_bytes = curr -> disk_total_bytes ;
7609
+ curr -> commit_bytes_used = curr -> bytes_used ;
7625
7610
}
7626
- mutex_unlock (& fs_info -> chunk_mutex );
7611
+ mutex_unlock (& trans -> fs_info -> chunk_mutex );
7627
7612
}
7628
7613
7629
7614
void btrfs_set_fs_info_ptr (struct btrfs_fs_info * fs_info )
0 commit comments