]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
btrfs: fix transaction commit blocking during trim of unallocated space
authorjinbaohong <jinbaohong@synology.com>
Wed, 28 Jan 2026 07:06:41 +0000 (07:06 +0000)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 06:56:25 +0000 (07:56 +0100)
commitb291ad4458df8311626dfa0a089918f6a542d6bc
treefdfbe0532b6445ed7aa1fb609286403bba243f53
parentbfb670b9183b0e4ba660aff2e396ec1cc01d0761
btrfs: fix transaction commit blocking during trim of unallocated space

When trimming unallocated space, btrfs_trim_fs() holds the device_list_mutex
for the entire duration while iterating through all devices. On large
filesystems with significant unallocated space, this operation can take
minutes to hours on large storage systems.

This causes a problem because btrfs_run_dev_stats(), which is called
during transaction commit, also requires device_list_mutex:

  btrfs_trim_fs()
    mutex_lock(&fs_devices->device_list_mutex)
    list_for_each_entry(device, ...)
      btrfs_trim_free_extents(device)
    mutex_unlock(&fs_devices->device_list_mutex)

  commit_transaction()
    btrfs_run_dev_stats()
      mutex_lock(&fs_devices->device_list_mutex)  // blocked!
      ...

While trim is running, all transaction commits are blocked waiting for
the mutex.

Fix this by refactoring btrfs_trim_free_extents() to process devices in
bounded chunks (up to 2GB per iteration) and release device_list_mutex
between chunks.

Signed-off-by: robbieko <robbieko@synology.com>
Signed-off-by: jinbaohong <jinbaohong@synology.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-tree.c
fs/btrfs/fs.h