Skip to content

Commit 7a670b4

Browse files
luca020400gregkh
authored andcommitted
btrfs: add cancellation points to trim loops
commit 6931385 upstream. There are reports that system cannot suspend due to running trim because the task responsible for trimming the device isn't able to finish in time, especially since we have a free extent discarding phase, which can trim a lot of unallocated space. There are no limits on the trim size (unlike the block group part). Since trime isn't a critical call it can be interrupted at any time, in such cases we stop the trim, report the amount of discarded bytes and return an error. Link: https://bugzilla.kernel.org/show_bug.cgi?id=219180 Link: https://bugzilla.suse.com/show_bug.cgi?id=1229737 CC: [email protected] # 5.15+ Signed-off-by: Luca Stefani <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d11f14a commit 7a670b4

File tree

3 files changed

+15
-3
lines changed

3 files changed

+15
-3
lines changed

fs/btrfs/extent-tree.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,11 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
13191319
start += bytes_to_discard;
13201320
bytes_left -= bytes_to_discard;
13211321
*discarded_bytes += bytes_to_discard;
1322+
1323+
if (btrfs_trim_interrupted()) {
1324+
ret = -ERESTARTSYS;
1325+
break;
1326+
}
13221327
}
13231328

13241329
return ret;
@@ -6097,7 +6102,7 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
60976102
start += len;
60986103
*trimmed += bytes;
60996104

6100-
if (fatal_signal_pending(current)) {
6105+
if (btrfs_trim_interrupted()) {
61016106
ret = -ERESTARTSYS;
61026107
break;
61036108
}

fs/btrfs/free-space-cache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3808,7 +3808,7 @@ static int trim_no_bitmap(struct btrfs_block_group *block_group,
38083808
if (async && *total_trimmed)
38093809
break;
38103810

3811-
if (fatal_signal_pending(current)) {
3811+
if (btrfs_trim_interrupted()) {
38123812
ret = -ERESTARTSYS;
38133813
break;
38143814
}
@@ -3999,7 +3999,7 @@ static int trim_bitmaps(struct btrfs_block_group *block_group,
39993999
}
40004000
block_group->discard_cursor = start;
40014001

4002-
if (fatal_signal_pending(current)) {
4002+
if (btrfs_trim_interrupted()) {
40034003
if (start != offset)
40044004
reset_trimming_bitmap(ctl, offset);
40054005
ret = -ERESTARTSYS;

fs/btrfs/free-space-cache.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef BTRFS_FREE_SPACE_CACHE_H
77
#define BTRFS_FREE_SPACE_CACHE_H
88

9+
#include <linux/freezer.h>
10+
911
/*
1012
* This is the trim state of an extent or bitmap.
1113
*
@@ -43,6 +45,11 @@ static inline bool btrfs_free_space_trimming_bitmap(
4345
return (info->trim_state == BTRFS_TRIM_STATE_TRIMMING);
4446
}
4547

48+
static inline bool btrfs_trim_interrupted(void)
49+
{
50+
return fatal_signal_pending(current) || freezing(current);
51+
}
52+
4653
/*
4754
* Deltas are an effective way to populate global statistics. Give macro names
4855
* to make it clear what we're doing. An example is discard_extents in

0 commit comments

Comments
 (0)