Skip to content

Commit 74a6325

Browse files
committed
Merge tag 'for-6.15-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix potential endless loop when discarding a block group when disabling discard - reinstate message when setting a large value of mount option 'commit' - fix a folio leak when async extent submission fails * tag 'for-6.15-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: add back warning for mount option commit values exceeding 300 btrfs: fix folio leak in submit_one_async_extent() btrfs: fix discard worker infinite loop after disabling discard
2 parents c94d59a + 4ce2aff commit 74a6325

File tree

4 files changed

+27
-2
lines changed

4 files changed

+27
-2
lines changed

fs/btrfs/discard.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ static void __add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
9494
struct btrfs_block_group *block_group)
9595
{
9696
lockdep_assert_held(&discard_ctl->lock);
97-
if (!btrfs_run_discard_work(discard_ctl))
98-
return;
9997

10098
if (list_empty(&block_group->discard_list) ||
10199
block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED) {
@@ -118,6 +116,9 @@ static void add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
118116
if (!btrfs_is_block_group_data_only(block_group))
119117
return;
120118

119+
if (!btrfs_run_discard_work(discard_ctl))
120+
return;
121+
121122
spin_lock(&discard_ctl->lock);
122123
__add_to_discard_list(discard_ctl, block_group);
123124
spin_unlock(&discard_ctl->lock);
@@ -244,6 +245,18 @@ static struct btrfs_block_group *peek_discard_list(
244245
block_group->used != 0) {
245246
if (btrfs_is_block_group_data_only(block_group)) {
246247
__add_to_discard_list(discard_ctl, block_group);
248+
/*
249+
* The block group must have been moved to other
250+
* discard list even if discard was disabled in
251+
* the meantime or a transaction abort happened,
252+
* otherwise we can end up in an infinite loop,
253+
* always jumping into the 'again' label and
254+
* keep getting this block group over and over
255+
* in case there are no other block groups in
256+
* the discard lists.
257+
*/
258+
ASSERT(block_group->discard_index !=
259+
BTRFS_DISCARD_INDEX_UNUSED);
247260
} else {
248261
list_del_init(&block_group->discard_list);
249262
btrfs_put_block_group(block_group);

fs/btrfs/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ enum {
300300
#define BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR 0ULL
301301

302302
#define BTRFS_DEFAULT_COMMIT_INTERVAL (30)
303+
#define BTRFS_WARNING_COMMIT_INTERVAL (300)
303304
#define BTRFS_DEFAULT_MAX_INLINE (2048)
304305

305306
struct btrfs_dev_replace {

fs/btrfs/inode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
11091109
struct extent_state *cached = NULL;
11101110
struct extent_map *em;
11111111
int ret = 0;
1112+
bool free_pages = false;
11121113
u64 start = async_extent->start;
11131114
u64 end = async_extent->start + async_extent->ram_size - 1;
11141115

@@ -1129,7 +1130,10 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
11291130
}
11301131

11311132
if (async_extent->compress_type == BTRFS_COMPRESS_NONE) {
1133+
ASSERT(!async_extent->folios);
1134+
ASSERT(async_extent->nr_folios == 0);
11321135
submit_uncompressed_range(inode, async_extent, locked_folio);
1136+
free_pages = true;
11331137
goto done;
11341138
}
11351139

@@ -1145,6 +1149,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
11451149
* fall back to uncompressed.
11461150
*/
11471151
submit_uncompressed_range(inode, async_extent, locked_folio);
1152+
free_pages = true;
11481153
goto done;
11491154
}
11501155

@@ -1186,6 +1191,8 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
11861191
done:
11871192
if (async_chunk->blkcg_css)
11881193
kthread_associate_blkcg(NULL);
1194+
if (free_pages)
1195+
free_async_extent_pages(async_extent);
11891196
kfree(async_extent);
11901197
return;
11911198

fs/btrfs/super.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,10 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
569569
break;
570570
case Opt_commit_interval:
571571
ctx->commit_interval = result.uint_32;
572+
if (ctx->commit_interval > BTRFS_WARNING_COMMIT_INTERVAL) {
573+
btrfs_warn(NULL, "excessive commit interval %u, use with care",
574+
ctx->commit_interval);
575+
}
572576
if (ctx->commit_interval == 0)
573577
ctx->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
574578
break;

0 commit comments

Comments
 (0)