btrfs: log swapfile activation/deactivation and warn about pinned block groups

A swap file on btrfs will pin down block groups that cover the swap file
extent.

Pinned down block groups will be skipped for scrub and relocation.

These degradation on critical btrfs maintenance operations is never
properly educated to end users, and have already caused problems
including:

- Scrub finished too quick
  Because the enabled swap file has pinned down most of the block
  groups. Thus any file extents in those block groups, even not utilized
  by the swap file, will be skipped from scrub.

- Unbalanced data and metadata usage, meanwhile relocation won't help
  The same reason, pinned down block groups will not be considered as
  relocation target, thus data extents that are not utilized by the swap
  file can still be skipped from relocation.

Although we already have kernel messages for both scrub and balance, the
balance one is still info level.

To better communicate those potential long term problems, add the
following output into dmesg:

- Change the message level to warn for __btrfs_balance()

- Total pinned down block group number and size during swapfile activation
- Total released block group number and size during swapfile deactivation
  The above messages have info level.

- The fact that pinned down block groups will not be scrubbed nor
  balanced
  The above message has warning level.

The example output would look like the following, for enabling a 1.2G
swapfile, which pinned down 2G block groups:

 BTRFS info (device dm-3): swapfile activated on root 5 ino 257, pinned down 2147483648 bytes from 2 block group(s)
 BTRFS warning (device dm-3): block groups with swapfile extents will not be scrubbed or balanced
 Adding 1257468k swap on /mnt/btrfs/foobar.  Priority:-1 extents:1 across:1257468k
 BTRFS info (device dm-3): swapfile deactivated on root 5 ino 257, released 2147483648 bytes from 2 block group(s)

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2026-06-16 09:24:22 +09:30 committed by David Sterba
parent 030d3514c6
commit 0d99b3b1cf
2 changed files with 27 additions and 3 deletions

View File

@ -10194,6 +10194,8 @@ static void btrfs_free_swapfile_pins(struct inode *inode)
struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
struct btrfs_swapfile_pin *sp;
struct rb_node *node, *next;
u64 bg_bytes_released = 0;
u32 bg_nr_released = 0;
spin_lock(&fs_info->swapfile_pins_lock);
node = rb_first(&fs_info->swapfile_pins);
@ -10203,15 +10205,24 @@ static void btrfs_free_swapfile_pins(struct inode *inode)
if (sp->inode == inode) {
rb_erase(&sp->node, &fs_info->swapfile_pins);
if (sp->is_block_group) {
btrfs_dec_block_group_swap_extents(sp->ptr,
struct btrfs_block_group *bg = sp->ptr;
bg_bytes_released += bg->length;
bg_nr_released++;
btrfs_dec_block_group_swap_extents(bg,
sp->bg_extent_count);
btrfs_put_block_group(sp->ptr);
btrfs_put_block_group(bg);
}
kfree(sp);
}
node = next;
}
spin_unlock(&fs_info->swapfile_pins_lock);
btrfs_info(fs_info,
"swapfile deactivated on root %llu ino %llu, released %llu bytes from %u block group(s)",
btrfs_root_id(BTRFS_I(inode)->root),
btrfs_ino(BTRFS_I(inode)), bg_bytes_released,
bg_nr_released);
}
struct btrfs_swap_info {
@ -10289,8 +10300,10 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
struct btrfs_backref_share_check_ctx *backref_ctx = NULL;
struct btrfs_path *path = NULL;
int ret = 0;
u32 pinned_bg_nr = 0;
u64 isize;
u64 prev_extent_end = 0;
u64 pinned_bg_size = 0;
/*
* Acquire the inode's mmap lock to prevent races with memory mapped
@ -10540,6 +10553,9 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
ret = 0;
else
goto out;
} else {
pinned_bg_size += bg->length;
pinned_bg_nr++;
}
if (bsi.block_len &&
@ -10587,6 +10603,14 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
if (ret)
return ret;
btrfs_info(fs_info,
"swapfile activated on root %llu ino %llu, pinned down %llu bytes from %u block group(s)",
btrfs_root_id(BTRFS_I(inode)->root),
btrfs_ino(BTRFS_I(inode)),
pinned_bg_size, pinned_bg_nr);
btrfs_warn(fs_info,
"block groups with swapfile extents will not be scrubbed or balanced");
if (device)
sis->bdev = device->bdev;
*span = bsi.highest_ppage - bsi.lowest_ppage + 1;

View File

@ -4588,7 +4588,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
if (ret == -ENOSPC) {
enospc_errors++;
} else if (ret == -ETXTBSY) {
btrfs_info(fs_info,
btrfs_warn(fs_info,
"skipping relocation of block group %llu due to active swapfile",
found_key.offset);
ret = 0;