@@ -295,7 +295,7 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
295
295
void btrfs_update_space_info (struct btrfs_fs_info * info , u64 flags ,
296
296
u64 total_bytes , u64 bytes_used ,
297
297
u64 bytes_readonly , u64 bytes_zone_unusable ,
298
- struct btrfs_space_info * * space_info )
298
+ bool active , struct btrfs_space_info * * space_info )
299
299
{
300
300
struct btrfs_space_info * found ;
301
301
int factor ;
@@ -306,6 +306,8 @@ void btrfs_update_space_info(struct btrfs_fs_info *info, u64 flags,
306
306
ASSERT (found );
307
307
spin_lock (& found -> lock );
308
308
found -> total_bytes += total_bytes ;
309
+ if (active )
310
+ found -> active_total_bytes += total_bytes ;
309
311
found -> disk_total += total_bytes * factor ;
310
312
found -> bytes_used += bytes_used ;
311
313
found -> disk_used += bytes_used * factor ;
@@ -369,6 +371,22 @@ static u64 calc_available_free_space(struct btrfs_fs_info *fs_info,
369
371
return avail ;
370
372
}
371
373
374
+ static inline u64 writable_total_bytes (struct btrfs_fs_info * fs_info ,
375
+ struct btrfs_space_info * space_info )
376
+ {
377
+ /*
378
+ * On regular filesystem, all total_bytes are always writable. On zoned
379
+ * filesystem, there may be a limitation imposed by max_active_zones.
380
+ * For metadata allocation, we cannot finish an existing active block
381
+ * group to avoid a deadlock. Thus, we need to consider only the active
382
+ * groups to be writable for metadata space.
383
+ */
384
+ if (!btrfs_is_zoned (fs_info ) || (space_info -> flags & BTRFS_BLOCK_GROUP_DATA ))
385
+ return space_info -> total_bytes ;
386
+
387
+ return space_info -> active_total_bytes ;
388
+ }
389
+
372
390
int btrfs_can_overcommit (struct btrfs_fs_info * fs_info ,
373
391
struct btrfs_space_info * space_info , u64 bytes ,
374
392
enum btrfs_reserve_flush_enum flush )
@@ -383,7 +401,7 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
383
401
used = btrfs_space_info_used (space_info , true);
384
402
avail = calc_available_free_space (fs_info , space_info , flush );
385
403
386
- if (used + bytes < space_info -> total_bytes + avail )
404
+ if (used + bytes < writable_total_bytes ( fs_info , space_info ) + avail )
387
405
return 1 ;
388
406
return 0 ;
389
407
}
@@ -419,7 +437,7 @@ void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
419
437
ticket = list_first_entry (head , struct reserve_ticket , list );
420
438
421
439
/* Check and see if our ticket can be satisfied now. */
422
- if ((used + ticket -> bytes <= space_info -> total_bytes ) ||
440
+ if ((used + ticket -> bytes <= writable_total_bytes ( fs_info , space_info ) ) ||
423
441
btrfs_can_overcommit (fs_info , space_info , ticket -> bytes ,
424
442
flush )) {
425
443
btrfs_space_info_update_bytes_may_use (fs_info ,
@@ -750,6 +768,7 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
750
768
{
751
769
u64 used ;
752
770
u64 avail ;
771
+ u64 total ;
753
772
u64 to_reclaim = space_info -> reclaim_size ;
754
773
755
774
lockdep_assert_held (& space_info -> lock );
@@ -764,8 +783,9 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
764
783
* space. If that's the case add in our overage so we make sure to put
765
784
* appropriate pressure on the flushing state machine.
766
785
*/
767
- if (space_info -> total_bytes + avail < used )
768
- to_reclaim += used - (space_info -> total_bytes + avail );
786
+ total = writable_total_bytes (fs_info , space_info );
787
+ if (total + avail < used )
788
+ to_reclaim += used - (total + avail );
769
789
770
790
return to_reclaim ;
771
791
}
@@ -775,9 +795,12 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
775
795
{
776
796
u64 global_rsv_size = fs_info -> global_block_rsv .reserved ;
777
797
u64 ordered , delalloc ;
778
- u64 thresh = div_factor_fine (space_info -> total_bytes , 90 );
798
+ u64 total = writable_total_bytes (fs_info , space_info );
799
+ u64 thresh ;
779
800
u64 used ;
780
801
802
+ thresh = div_factor_fine (total , 90 );
803
+
781
804
lockdep_assert_held (& space_info -> lock );
782
805
783
806
/* If we're just plain full then async reclaim just slows us down. */
@@ -839,8 +862,8 @@ static bool need_preemptive_reclaim(struct btrfs_fs_info *fs_info,
839
862
BTRFS_RESERVE_FLUSH_ALL );
840
863
used = space_info -> bytes_used + space_info -> bytes_reserved +
841
864
space_info -> bytes_readonly + global_rsv_size ;
842
- if (used < space_info -> total_bytes )
843
- thresh += space_info -> total_bytes - used ;
865
+ if (used < total )
866
+ thresh += total - used ;
844
867
thresh >>= space_info -> clamp ;
845
868
846
869
used = space_info -> bytes_pinned ;
@@ -1557,7 +1580,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info,
1557
1580
* can_overcommit() to ensure we can overcommit to continue.
1558
1581
*/
1559
1582
if (!pending_tickets &&
1560
- ((used + orig_bytes <= space_info -> total_bytes ) ||
1583
+ ((used + orig_bytes <= writable_total_bytes ( fs_info , space_info ) ) ||
1561
1584
btrfs_can_overcommit (fs_info , space_info , orig_bytes , flush ))) {
1562
1585
btrfs_space_info_update_bytes_may_use (fs_info , space_info ,
1563
1586
orig_bytes );
0 commit comments