summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2023-07-26 18:57:03 +0300
committerDavid Sterba <dsterba@suse.com>2023-08-21 15:52:17 +0300
commit1b6948acb854b88162f273a26f9324d167051700 (patch)
tree8820081863bef8e2ea1c071d30308543c04ce71a /fs/btrfs
parent1ff9fee3bd2e865c81d29684dd40a91698f7999b (diff)
downloadlinux-1b6948acb854b88162f273a26f9324d167051700.tar.xz
btrfs: don't steal space from global rsv after a transaction abort
When doing a priority metadata space reclaim, while we are going through the flush states and running their respective operations, it's possible that a transaction abort happened, for example when running delayed refs we hit -ENOSPC or in the critical section of transaction commit we failed with -ENOSPC or some other error. In these cases a transaction was aborted and the fs turned into error state. If that happened, then it makes no sense to steal from the global block reserve and return success to the caller if the stealing was successful - the caller will later get an error when attempting to modify the fs. Instead make the ticket fail if we have the fs in error state and don't attempt to steal from the global rsv, as it's not only it's pointless, it also simplifies debugging some -ENOSPC problems. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/space-info.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
index de0044283e29..5b1b71e029ad 100644
--- a/fs/btrfs/space-info.c
+++ b/fs/btrfs/space-info.c
@@ -1418,8 +1418,18 @@ static void priority_reclaim_metadata_space(struct btrfs_fs_info *fs_info,
}
}
- /* Attempt to steal from the global rsv if we can. */
- if (!steal_from_global_rsv(fs_info, space_info, ticket)) {
+ /*
+ * Attempt to steal from the global rsv if we can, except if the fs was
+ * turned into error mode due to a transaction abort when flushing space
+ * above, in that case fail with -EROFS instead of returning success to
+ * the caller if we can steal from the global rsv - this is just to have
+ * caller fail immeditelly instead of later when trying to modify the
+ * fs, making it easier to debug -ENOSPC problems.
+ */
+ if (BTRFS_FS_ERROR(fs_info)) {
+ ticket->error = -EROFS;
+ remove_ticket(space_info, ticket);
+ } else if (!steal_from_global_rsv(fs_info, space_info, ticket)) {
ticket->error = -ENOSPC;
remove_ticket(space_info, ticket);
}