* [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes
@ 2024-01-04 19:48 Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 1/2] btrfs: don't abort filesystem when attempting to snapshot deleted subvolume Omar Sandoval
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Omar Sandoval @ 2024-01-04 19:48 UTC (permalink / raw)
To: linux-btrfs; +Cc: kernel-team
From: Omar Sandoval <osandov@fb.com>
Hi,
This small series fixes a couple of bugs that can happen when trying to
snapshot a deleted subvolume. Patch 1 fixes a filesystem abort that we
hit in production. Patch 2 fixes another issue that Sweet Tea spotted
when reviewing patch 1.
An fstest was sent previously [1].
Thanks!
Changes from v1 [2]:
- Rebased on latest misc-next.
- Added patch 2.
1: https://lore.kernel.org/linux-btrfs/62415ffc97ff2db4fa65cdd6f9db6ddead8105cd.1703010806.git.osandov@osandov.com/
2: https://lore.kernel.org/linux-btrfs/068014bd3e90668525c295660862db2932e25087.1703010314.git.osandov@fb.com/
Omar Sandoval (2):
btrfs: don't abort filesystem when attempting to snapshot deleted
subvolume
btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of
subvolume being deleted
fs/btrfs/inode.c | 22 +++++++++++++---------
fs/btrfs/ioctl.c | 3 +++
2 files changed, 16 insertions(+), 9 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] btrfs: don't abort filesystem when attempting to snapshot deleted subvolume
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
@ 2024-01-04 19:48 ` Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 2/2] btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted Omar Sandoval
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Omar Sandoval @ 2024-01-04 19:48 UTC (permalink / raw)
To: linux-btrfs; +Cc: kernel-team
From: Omar Sandoval <osandov@fb.com>
If the source file descriptor to the snapshot ioctl refers to a deleted
subvolume, we get the following abort:
------------[ cut here ]------------
BTRFS: Transaction aborted (error -2)
WARNING: CPU: 0 PID: 833 at fs/btrfs/transaction.c:1875 create_pending_snapshot+0x1040/0x1190 [btrfs]
Modules linked in: pata_acpi btrfs ata_piix libata scsi_mod virtio_net blake2b_generic xor net_failover virtio_rng failover scsi_common rng_core raid6_pq libcrc32c
CPU: 0 PID: 833 Comm: t_snapshot_dele Not tainted 6.7.0-rc6 #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-1.fc39 04/01/2014
RIP: 0010:create_pending_snapshot+0x1040/0x1190 [btrfs]
Code: e9 44 fe ff ff 44 89 e6 48 c7 c7 f8 59 7b c0 e8 d6 f4 a3 f7 0f 0b e9 4c fa ff ff 44 89 e6 48 c7 c7 f8 59 7b c0 e8 c0 f4 a3 f7 <0f> 0b e9 ef fe ff ff 44 89 e6 48 c7 c7 f8 59 7b c0 e8 aa f4 a3 f7
RSP: 0018:ffffa09c01337af8 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffff9982053e7c78 RCX: 0000000000000027
RDX: ffff99827dc20848 RSI: 0000000000000001 RDI: ffff99827dc20840
RBP: ffffa09c01337c00 R08: 0000000000000000 R09: ffffa09c01337998
R10: 0000000000000003 R11: ffffffffb96da248 R12: fffffffffffffffe
R13: ffff99820535bb28 R14: ffff99820b7bd000 R15: ffff99820381ea80
FS: 00007fe20aadabc0(0000) GS:ffff99827dc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000559a120b502f CR3: 00000000055b6000 CR4: 00000000000006f0
Call Trace:
<TASK>
? create_pending_snapshot+0x1040/0x1190 [btrfs]
? __warn+0x81/0x130
? create_pending_snapshot+0x1040/0x1190 [btrfs]
? report_bug+0x171/0x1a0
? handle_bug+0x3a/0x70
? exc_invalid_op+0x17/0x70
? asm_exc_invalid_op+0x1a/0x20
? create_pending_snapshot+0x1040/0x1190 [btrfs]
? create_pending_snapshot+0x1040/0x1190 [btrfs]
create_pending_snapshots+0x92/0xc0 [btrfs]
btrfs_commit_transaction+0x66b/0xf40 [btrfs]
btrfs_mksubvol+0x301/0x4d0 [btrfs]
btrfs_mksnapshot+0x80/0xb0 [btrfs]
__btrfs_ioctl_snap_create+0x1c2/0x1d0 [btrfs]
btrfs_ioctl_snap_create_v2+0xc4/0x150 [btrfs]
btrfs_ioctl+0x8a6/0x2650 [btrfs]
? kmem_cache_free+0x22/0x340
? do_sys_openat2+0x97/0xe0
__x64_sys_ioctl+0x97/0xd0
do_syscall_64+0x46/0xf0
entry_SYSCALL_64_after_hwframe+0x6e/0x76
RIP: 0033:0x7fe20abe83af
Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 18 48 8b 44 24 18 64 48 2b 04 25 28 00 00
RSP: 002b:00007ffe6eff1360 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007fe20abe83af
RDX: 00007ffe6eff23c0 RSI: 0000000050009417 RDI: 0000000000000003
RBP: 0000000000000003 R08: 0000000000000000 R09: 00007fe20ad16cd0
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffe6eff13c0 R14: 00007fe20ad45000 R15: 0000559a120b6d58
</TASK>
---[ end trace 0000000000000000 ]---
BTRFS: error (device vdc: state A) in create_pending_snapshot:1875: errno=-2 No such entry
BTRFS info (device vdc: state EA): forced readonly
BTRFS warning (device vdc: state EA): Skipping commit of aborted transaction.
BTRFS: error (device vdc: state EA) in cleanup_transaction:2055: errno=-2 No such entry
This happens because create_pending_snapshot() initializes the new root
item as a copy of the source root item. This includes the refs field,
which is 0 for a deleted subvolume. The call to btrfs_insert_root()
therefore inserts a root with refs == 0. btrfs_get_new_fs_root() then
finds the root and returns -ENOENT if refs == 0, which causes
create_pending_snapshot() to abort.
Fix it by checking the source root's refs before attempting the snapshot
(but after locking subvol_sem to avoid racing with deletion).
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
fs/btrfs/ioctl.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a1743904202b..0af214c8bef4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -790,6 +790,9 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
return -EOPNOTSUPP;
}
+ if (btrfs_root_refs(&root->root_item) == 0)
+ return -ENOENT;
+
if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
return -EINVAL;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 1/2] btrfs: don't abort filesystem when attempting to snapshot deleted subvolume Omar Sandoval
@ 2024-01-04 19:48 ` Omar Sandoval
2024-01-05 20:11 ` [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Sweet Tea Dorminy
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Omar Sandoval @ 2024-01-04 19:48 UTC (permalink / raw)
To: linux-btrfs; +Cc: kernel-team
From: Omar Sandoval <osandov@fb.com>
Sweet Tea spotted a race between subvolume deletion and snapshotting
that can result in the root item for the snapshot having the
BTRFS_ROOT_SUBVOL_DEAD flag set. The race is:
Thread 1 | Thread 2
----------------------------------------------|----------
btrfs_delete_subvolume |
btrfs_set_root_flags(BTRFS_ROOT_SUBVOL_DEAD)|
|btrfs_mksubvol
| down_read(subvol_sem)
| create_snapshot
| ...
| create_pending_snapshot
| copy root item from source
down_write(subvol_sem) |
This flag is only checked in send and swap activate, which this would
cause to fail mysteriously.
create_snapshot() now checks the root refs to reject a deleted
subvolume, so we can fix this by locking subvol_sem earlier so that the
BTRFS_ROOT_SUBVOL_DEAD flag and the root refs are updated atomically.
Reported-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
fs/btrfs/inode.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b3e39610cc95..7bcc1c03437a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4458,6 +4458,8 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry)
u64 root_flags;
int ret;
+ down_write(&fs_info->subvol_sem);
+
/*
* Don't allow to delete a subvolume with send in progress. This is
* inside the inode lock so the error handling that has to drop the bit
@@ -4469,25 +4471,25 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry)
btrfs_warn(fs_info,
"attempt to delete subvolume %llu during send",
dest->root_key.objectid);
- return -EPERM;
+ ret = -EPERM;
+ goto out_up_write;
}
if (atomic_read(&dest->nr_swapfiles)) {
spin_unlock(&dest->root_item_lock);
btrfs_warn(fs_info,
"attempt to delete subvolume %llu with active swapfile",
root->root_key.objectid);
- return -EPERM;
+ ret = -EPERM;
+ goto out_up_write;
}
root_flags = btrfs_root_flags(&dest->root_item);
btrfs_set_root_flags(&dest->root_item,
root_flags | BTRFS_ROOT_SUBVOL_DEAD);
spin_unlock(&dest->root_item_lock);
- down_write(&fs_info->subvol_sem);
-
ret = may_destroy_subvol(dest);
if (ret)
- goto out_up_write;
+ goto out_undead;
btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP);
/*
@@ -4497,7 +4499,7 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry)
*/
ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, 5, true);
if (ret)
- goto out_up_write;
+ goto out_undead;
trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans)) {
@@ -4563,15 +4565,17 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry)
inode->i_flags |= S_DEAD;
out_release:
btrfs_subvolume_release_metadata(root, &block_rsv);
-out_up_write:
- up_write(&fs_info->subvol_sem);
+out_undead:
if (ret) {
spin_lock(&dest->root_item_lock);
root_flags = btrfs_root_flags(&dest->root_item);
btrfs_set_root_flags(&dest->root_item,
root_flags & ~BTRFS_ROOT_SUBVOL_DEAD);
spin_unlock(&dest->root_item_lock);
- } else {
+ }
+out_up_write:
+ up_write(&fs_info->subvol_sem);
+ if (!ret) {
d_invalidate(dentry);
btrfs_prune_dentries(dest);
ASSERT(dest->send_in_progress == 0);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 1/2] btrfs: don't abort filesystem when attempting to snapshot deleted subvolume Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 2/2] btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted Omar Sandoval
@ 2024-01-05 20:11 ` Sweet Tea Dorminy
2024-01-06 0:58 ` Anand Jain
2024-01-08 19:39 ` David Sterba
4 siblings, 0 replies; 6+ messages in thread
From: Sweet Tea Dorminy @ 2024-01-05 20:11 UTC (permalink / raw)
To: Omar Sandoval, linux-btrfs; +Cc: kernel-team
On 1/4/24 14:48, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> Hi,
>
> This small series fixes a couple of bugs that can happen when trying to
> snapshot a deleted subvolume. Patch 1 fixes a filesystem abort that we
> hit in production. Patch 2 fixes another issue that Sweet Tea spotted
> when reviewing patch 1.
>
> An fstest was sent previously [1].
>
> Thanks!
>
> Changes from v1 [2]:
>
> - Rebased on latest misc-next.
> - Added patch 2.
>
> 1: https://lore.kernel.org/linux-btrfs/62415ffc97ff2db4fa65cdd6f9db6ddead8105cd.1703010806.git.osandov@osandov.com/
> 2: https://lore.kernel.org/linux-btrfs/068014bd3e90668525c295660862db2932e25087.1703010314.git.osandov@fb.com/
>
> Omar Sandoval (2):
> btrfs: don't abort filesystem when attempting to snapshot deleted
> subvolume
> btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of
> subvolume being deleted
>
> fs/btrfs/inode.c | 22 +++++++++++++---------
> fs/btrfs/ioctl.c | 3 +++
> 2 files changed, 16 insertions(+), 9 deletions(-)
>
For the series:
Reviewed-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
` (2 preceding siblings ...)
2024-01-05 20:11 ` [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Sweet Tea Dorminy
@ 2024-01-06 0:58 ` Anand Jain
2024-01-08 19:39 ` David Sterba
4 siblings, 0 replies; 6+ messages in thread
From: Anand Jain @ 2024-01-06 0:58 UTC (permalink / raw)
To: Omar Sandoval, linux-btrfs; +Cc: kernel-team
On 1/5/24 03:48, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> Hi,
>
> This small series fixes a couple of bugs that can happen when trying to
> snapshot a deleted subvolume. Patch 1 fixes a filesystem abort that we
> hit in production. Patch 2 fixes another issue that Sweet Tea spotted
> when reviewing patch 1.
>
> An fstest was sent previously [1].
>
> Thanks!
>
> Changes from v1 [2]:
>
> - Rebased on latest misc-next.
> - Added patch 2.
>
> 1: https://lore.kernel.org/linux-btrfs/62415ffc97ff2db4fa65cdd6f9db6ddead8105cd.1703010806.git.osandov@osandov.com/
> 2: https://lore.kernel.org/linux-btrfs/068014bd3e90668525c295660862db2932e25087.1703010314.git.osandov@fb.com/
>
> Omar Sandoval (2):
> btrfs: don't abort filesystem when attempting to snapshot deleted
> subvolume
> btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of
> subvolume being deleted
>
Looks good.
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Thx, Anand
> fs/btrfs/inode.c | 22 +++++++++++++---------
> fs/btrfs/ioctl.c | 3 +++
> 2 files changed, 16 insertions(+), 9 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
` (3 preceding siblings ...)
2024-01-06 0:58 ` Anand Jain
@ 2024-01-08 19:39 ` David Sterba
4 siblings, 0 replies; 6+ messages in thread
From: David Sterba @ 2024-01-08 19:39 UTC (permalink / raw)
To: Omar Sandoval; +Cc: linux-btrfs, kernel-team
On Thu, Jan 04, 2024 at 11:48:45AM -0800, Omar Sandoval wrote:
> From: Omar Sandoval <osandov@fb.com>
>
> Hi,
>
> This small series fixes a couple of bugs that can happen when trying to
> snapshot a deleted subvolume. Patch 1 fixes a filesystem abort that we
> hit in production. Patch 2 fixes another issue that Sweet Tea spotted
> when reviewing patch 1.
>
> An fstest was sent previously [1].
>
> Thanks!
>
> Changes from v1 [2]:
>
> - Rebased on latest misc-next.
> - Added patch 2.
>
> 1: https://lore.kernel.org/linux-btrfs/62415ffc97ff2db4fa65cdd6f9db6ddead8105cd.1703010806.git.osandov@osandov.com/
> 2: https://lore.kernel.org/linux-btrfs/068014bd3e90668525c295660862db2932e25087.1703010314.git.osandov@fb.com/
>
> Omar Sandoval (2):
> btrfs: don't abort filesystem when attempting to snapshot deleted
> subvolume
> btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of
> subvolume being deleted
Added to misc-next, thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-01-08 19:39 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-04 19:48 [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 1/2] btrfs: don't abort filesystem when attempting to snapshot deleted subvolume Omar Sandoval
2024-01-04 19:48 ` [PATCH v2 2/2] btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted Omar Sandoval
2024-01-05 20:11 ` [PATCH v2 0/2] btrfs: subvolume deletion vs. snapshot fixes Sweet Tea Dorminy
2024-01-06 0:58 ` Anand Jain
2024-01-08 19:39 ` David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox