Skip to content

Commit

Permalink
ext4: do not let fstrim block system suspend
Browse files Browse the repository at this point in the history
[ Upstream commit 5229a65 ]

Len Brown has reported that system suspend sometimes fail due to
inability to freeze a task working in ext4_trim_fs() for one minute.
Trimming a large filesystem on a disk that slowly processes discard
requests can indeed take a long time. Since discard is just an advisory
call, it is perfectly fine to interrupt it at any time and the return
number of discarded blocks until that moment. Do that when we detect the
task is being frozen.

Cc: stable@kernel.org
Reported-by: Len Brown <lenb@kernel.org>
Suggested-by: Dave Chinner <david@fromorbit.com>
References: https://bugzilla.kernel.org/show_bug.cgi?id=216322
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230913150504.9054-2-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jankara authored and gregkh committed Oct 6, 2023
1 parent b4d5db1 commit 6bb88a0
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions fs/ext4/mballoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/nospec.h>
#include <linux/backing-dev.h>
#include <linux/freezer.h>
#include <trace/events/ext4.h>

/*
Expand Down Expand Up @@ -6430,6 +6431,11 @@ static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
EXT4_CLUSTER_BITS(sb);
}

static bool ext4_trim_interrupted(void)
{
return fatal_signal_pending(current) || freezing(current);
}

static int ext4_try_to_trim_range(struct super_block *sb,
struct ext4_buddy *e4b, ext4_grpblk_t start,
ext4_grpblk_t max, ext4_grpblk_t minblocks)
Expand Down Expand Up @@ -6463,8 +6469,8 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group))
free_count += next - start;
start = next + 1;

if (fatal_signal_pending(current))
return -ERESTARTSYS;
if (ext4_trim_interrupted())
return count;

if (need_resched()) {
ext4_unlock_group(sb, e4b->bd_group);
Expand Down Expand Up @@ -6586,6 +6592,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;

for (group = first_group; group <= last_group; group++) {
if (ext4_trim_interrupted())
break;
grp = ext4_get_group_info(sb, group);
if (!grp)
continue;
Expand Down

0 comments on commit 6bb88a0

Please sign in to comment.