Message ID | 28ff4b0398d52b27c93fac93297be8f0e2a18fab.1675853489.git.johannes.thumshirn@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: introduce RAID stripe tree | expand |
On Wed, Feb 08, 2023 at 02:57:42AM -0800, Johannes Thumshirn wrote: > As each stripe extent is tied to an extent item, delete the stripe extent > once the corresponding extent item is deleted. > > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- > fs/btrfs/extent-tree.c | 8 ++++++++ > fs/btrfs/raid-stripe-tree.c | 31 +++++++++++++++++++++++++++++++ > fs/btrfs/raid-stripe-tree.h | 2 ++ > 3 files changed, 41 insertions(+) > > diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c > index 50b3a2c3c0dd..f08ee7d9211c 100644 > --- a/fs/btrfs/extent-tree.c > +++ b/fs/btrfs/extent-tree.c > @@ -3238,6 +3238,14 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, > } > } > > + if (is_data) { > + ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes); > + if (ret) { > + btrfs_abort_transaction(trans, ret); > + return ret; > + } > + } > + We're still holding the path open, so now we have a lockdep thing of extent root -> RST, which will for sure bite us in the ass in the future. Push this part just under this part of the code, after the btrfs_release_path(). Also since we have a path here, add it to the arguments for btrfs_delete_raid_extent() so we don't have to allocate a new path. Thanks, Josef
On 08.02.23 21:00, Josef Bacik wrote: >> diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c >> index 50b3a2c3c0dd..f08ee7d9211c 100644 >> --- a/fs/btrfs/extent-tree.c >> +++ b/fs/btrfs/extent-tree.c >> @@ -3238,6 +3238,14 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, >> } >> } >> >> + if (is_data) { >> + ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes); >> + if (ret) { >> + btrfs_abort_transaction(trans, ret); >> + return ret; >> + } >> + } >> + > We're still holding the path open, so now we have a lockdep thing of extent root > -> RST, which will for sure bite us in the ass in the future. Push this part > just under this part of the code, after the btrfs_release_path(). > > Also since we have a path here, add it to the arguments for > btrfs_delete_raid_extent() so we don't have to allocate a new path. Not sure what you mean here. With below change, I'm getting this splat: bash-5.1# rm /mnt/test/test [ 46.519048] ------------[ cut here ]------------ [ 46.520012] WARNING: CPU: 0 PID: 80 at fs/btrfs/ctree.c:2050 btrfs_search_slot+0x99a/0xd50 [ 46.521652] CPU: 0 PID: 80 Comm: kworker/u8:8 Not tainted 6.2.0-rc7+ #657 [ 46.522883] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 [ 46.524575] Workqueue: events_unbound btrfs_preempt_reclaim_metadata_space [ 46.526016] RIP: 0010:btrfs_search_slot+0x99a/0xd50 [ 46.526911] Code: 00 e9 63 fb ff ff c7 44 24 44 08 00 00 00 89 c8 c7 44 24 28 08 00 00 00 e9 60 f7 ff ff 0f 0b 49 83 3c 24 00 0f 84 e9 f6 ff ff <0f> 0b e9 e2 f6 ff ff 0f 0b e8 38 2c db ff 85 c0 0f 85 5f f7 ff ff [ 46.530527] RSP: 0018:ffffc90000b5faf8 EFLAGS: 00010286 [ 46.531479] RAX: 0000000000000000 RBX: 00000000ffffffff RCX: ffff88810235b700 [ 46.532817] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff81ec6182 [ 46.534250] RBP: ffff8881056b8000 R08: 00000000ffffffff R09: 0000000000000001 [ 46.535524] R10: 0000000000001000 R11: 00000000000000d0 R12: ffff88810a75e230 [ 46.536968] R13: ffff88810524e000 R14: ffff88810a75e230 R15: 000000000000002d [ 46.538273] FS: 0000000000000000(0000) GS:ffff88842fc00000(0000) knlGS:0000000000000000 [ 46.539963] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 46.541085] CR2: 000055aea08c9410 CR3: 00000001122fa000 CR4: 0000000000350eb0 [ 46.542395] Call Trace: [ 46.542868] <TASK> [ 46.543448] ? set_extent_buffer_dirty+0x17/0x170 [ 46.544409] ? btrfs_mark_buffer_dirty+0xd7/0x100 [ 46.545270] ? btrfs_del_items+0x394/0x4c0 [ 46.546031] btrfs_delete_raid_extent+0x4a/0x80 [ 46.547015] __btrfs_free_extent+0x446/0x7e0 [ 46.547812] __btrfs_run_delayed_refs+0x331/0x1210 [ 46.548794] btrfs_run_delayed_refs+0x89/0x1b0 [ 46.549661] flush_space+0x392/0x5e0 [ 46.550418] ? _raw_spin_unlock+0x12/0x30 [ 46.551156] ? btrfs_get_alloc_profile+0xbd/0x1a0 [ 46.552095] btrfs_preempt_reclaim_metadata_space+0x96/0x1e0 [ 46.553191] process_one_work+0x1d9/0x3e0 [ 46.554038] worker_thread+0x4a/0x3c0 [ 46.554726] ? __pfx_worker_thread+0x10/0x10 [ 46.555514] kthread+0xf5/0x120 [ 46.556173] ? __pfx_kthread+0x10/0x10 [ 46.557020] ret_from_fork+0x2c/0x50 [ 46.557695] </TASK> [ 46.558107] ---[ end trace 0000000000000000 ]--- diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 10827b7db13c..c040c1c70075 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3238,20 +3238,23 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, } } - if (is_data) { - ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes); - if (ret) { - btrfs_abort_transaction(trans, ret); - return ret; - } - } - ret = btrfs_del_items(trans, extent_root, path, path->slots[0], num_to_del); if (ret) { btrfs_abort_transaction(trans, ret); goto out; } + + if (is_data) { + ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes, + path); + if (ret) { + btrfs_abort_transaction(trans, ret); + goto out; + } + } + + btrfs_release_path(path); ret = do_free_extent_accounting(trans, bytenr, num_bytes, is_data); diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index 8799a7abaf38..a60cdfaa9359 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -157,11 +157,11 @@ void btrfs_put_ordered_stripe(struct btrfs_fs_info *fs_info, } int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, - u64 length) + u64 length, struct btrfs_path *path) { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *stripe_root = btrfs_stripe_tree_root(fs_info); - struct btrfs_path *path; + // struct btrfs_path *path; struct btrfs_key stripe_key; int ret; @@ -172,9 +172,9 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, stripe_key.type = BTRFS_RAID_STRIPE_KEY; stripe_key.offset = length; - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + /* path = btrfs_alloc_path(); */ + /* if (!path) */ + /* return -ENOMEM; */ ret = btrfs_search_slot(trans, stripe_root, &stripe_key, path, -1, 1); if (ret < 0) @@ -182,7 +182,7 @@ int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, ret = btrfs_del_item(trans, stripe_root, path); out: - btrfs_free_path(path); + /* btrfs_free_path(path); */ return ret; } diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h index 371409351d60..fc415ec77c36 100644 --- a/fs/btrfs/raid-stripe-tree.h +++ b/fs/btrfs/raid-stripe-tree.h @@ -27,7 +27,7 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info, u32 stripe_index, struct btrfs_io_stripe *stripe); int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, - u64 length); + u64 length, struct btrfs_path *path); int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_ordered_stripe *stripe); int btrfs_insert_preallocated_raid_stripe(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 50b3a2c3c0dd..f08ee7d9211c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3238,6 +3238,14 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, } } + if (is_data) { + ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes); + if (ret) { + btrfs_abort_transaction(trans, ret); + return ret; + } + } + ret = btrfs_del_items(trans, extent_root, path, path->slots[0], num_to_del); if (ret) { diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c index d184cd9dc96e..ff5787a19454 100644 --- a/fs/btrfs/raid-stripe-tree.c +++ b/fs/btrfs/raid-stripe-tree.c @@ -122,6 +122,37 @@ void btrfs_put_ordered_stripe(struct btrfs_fs_info *fs_info, write_unlock(&fs_info->stripe_update_lock); } +int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, + u64 length) +{ + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *stripe_root = btrfs_stripe_tree_root(fs_info); + struct btrfs_path *path; + struct btrfs_key stripe_key; + int ret; + + if (!stripe_root) + return 0; + + stripe_key.objectid = start; + stripe_key.type = BTRFS_RAID_STRIPE_KEY; + stripe_key.offset = length; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + ret = btrfs_search_slot(trans, stripe_root, &stripe_key, path, -1, 1); + if (ret < 0) + goto out; + + ret = btrfs_del_item(trans, stripe_root, path); +out: + btrfs_free_path(path); + return ret; + +} + int btrfs_insert_preallocated_raid_stripe(struct btrfs_fs_info *fs_info, u64 start, u64 len) { diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h index 60d3f8489cc9..12d2f588b22d 100644 --- a/fs/btrfs/raid-stripe-tree.h +++ b/fs/btrfs/raid-stripe-tree.h @@ -22,6 +22,8 @@ struct btrfs_ordered_stripe { refcount_t ref; }; +int btrfs_delete_raid_extent(struct btrfs_trans_handle *trans, u64 start, + u64 length); int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans, struct btrfs_ordered_stripe *stripe); int btrfs_insert_preallocated_raid_stripe(struct btrfs_fs_info *fs_info,
As each stripe extent is tied to an extent item, delete the stripe extent once the corresponding extent item is deleted. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- fs/btrfs/extent-tree.c | 8 ++++++++ fs/btrfs/raid-stripe-tree.c | 31 +++++++++++++++++++++++++++++++ fs/btrfs/raid-stripe-tree.h | 2 ++ 3 files changed, 41 insertions(+)