| From 082b6c970f02fefd278c7833880cda29691a5f34 Mon Sep 17 00:00:00 2001 |
| From: Qu Wenruo <wqu@suse.com> |
| Date: Tue, 16 Jun 2020 10:17:37 +0800 |
| Subject: [PATCH] btrfs: free anon block device right after subvolume deletion |
| |
| commit 082b6c970f02fefd278c7833880cda29691a5f34 upstream. |
| |
| [BUG] |
| When a lot of subvolumes are created, there is a user report about |
| transaction aborted caused by slow anonymous block device reclaim: |
| |
| BTRFS: Transaction aborted (error -24) |
| WARNING: CPU: 17 PID: 17041 at fs/btrfs/transaction.c:1576 create_pending_snapshot+0xbc4/0xd10 [btrfs] |
| RIP: 0010:create_pending_snapshot+0xbc4/0xd10 [btrfs] |
| Call Trace: |
| create_pending_snapshots+0x82/0xa0 [btrfs] |
| btrfs_commit_transaction+0x275/0x8c0 [btrfs] |
| btrfs_mksubvol+0x4b9/0x500 [btrfs] |
| btrfs_ioctl_snap_create_transid+0x174/0x180 [btrfs] |
| btrfs_ioctl_snap_create_v2+0x11c/0x180 [btrfs] |
| btrfs_ioctl+0x11a4/0x2da0 [btrfs] |
| do_vfs_ioctl+0xa9/0x640 |
| ksys_ioctl+0x67/0x90 |
| __x64_sys_ioctl+0x1a/0x20 |
| do_syscall_64+0x5a/0x110 |
| entry_SYSCALL_64_after_hwframe+0x44/0xa9 |
| ---[ end trace 33f2f83f3d5250e9 ]--- |
| BTRFS: error (device sda1) in create_pending_snapshot:1576: errno=-24 unknown |
| BTRFS info (device sda1): forced readonly |
| BTRFS warning (device sda1): Skipping commit of aborted transaction. |
| BTRFS: error (device sda1) in cleanup_transaction:1831: errno=-24 unknown |
| |
| [CAUSE] |
| The anonymous device pool is shared and its size is 1M. It's possible to |
| hit that limit if the subvolume deletion is not fast enough and the |
| subvolumes to be cleaned keep the ids allocated. |
| |
| [WORKAROUND] |
| We can't avoid the anon device pool exhaustion but we can shorten the |
| time the id is attached to the subvolume root once the subvolume becomes |
| invisible to the user. |
| |
| Reported-by: Greed Rong <greedrong@gmail.com> |
| Link: https://lore.kernel.org/linux-btrfs/CA+UqX+NTrZ6boGnWHhSeZmEY5J76CTqmYjO2S+=tHJX7nb9DPw@mail.gmail.com/ |
| CC: stable@vger.kernel.org # 4.4+ |
| Reviewed-by: Josef Bacik <josef@toxicpanda.com> |
| Signed-off-by: Qu Wenruo <wqu@suse.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| |
| diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
| index 5d2ce8092531..f066cad2d039 100644 |
| --- a/fs/btrfs/inode.c |
| +++ b/fs/btrfs/inode.c |
| @@ -4026,6 +4026,8 @@ int btrfs_delete_subvolume(struct inode *dir, struct dentry *dentry) |
| } |
| } |
| |
| + free_anon_bdev(dest->anon_dev); |
| + dest->anon_dev = 0; |
| out_end_trans: |
| trans->block_rsv = NULL; |
| trans->bytes_reserved = 0; |
| -- |
| 2.27.0 |
| |