* [PATCH 0/4] btrfs: some cleanups for the log tree replay code
@ 2025-05-21 17:44 fdmanana
2025-05-21 17:44 ` [PATCH 1/4] btrfs: unfold transaction aborts when replaying log trees fdmanana
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: fdmanana @ 2025-05-21 17:44 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
A set of trivial cleanups after running into a bug I'm debugging where
replaying directory deletes is failing. Details in the change logs.
Filipe Manana (4):
btrfs: unfold transaction aborts when replaying log trees
btrfs: abort transaction during log replay if walk_log_tree() failed
btrfs: remove redundant path release when replaying a log tree
btrfs: simplify error detection flow during log replay
fs/btrfs/tree-log.c | 64 ++++++++++++++++++++++++++-------------------
1 file changed, 37 insertions(+), 27 deletions(-)
--
2.47.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] btrfs: unfold transaction aborts when replaying log trees
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
@ 2025-05-21 17:44 ` fdmanana
2025-05-21 17:44 ` [PATCH 2/4] btrfs: abort transaction during log replay if walk_log_tree() failed fdmanana
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: fdmanana @ 2025-05-21 17:44 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
We have a single line doing a transaction abort in case either we got an
error from btrfs_get_fs_root() different from -ENOENT or we got an error
from btrfs_pin_extent_for_log_replay(), making it hard to figure out which
function call failed when looking at a transaction abort massages and
stack trace in dmesg. Change this to have an explicit transaction abort
for each one of the two cases.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 97e933113b82..c1c4b8327229 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7255,6 +7255,11 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
true);
if (IS_ERR(wc.replay_dest)) {
ret = PTR_ERR(wc.replay_dest);
+ if (ret != -ENOENT) {
+ btrfs_put_root(log);
+ btrfs_abort_transaction(trans, ret);
+ goto error;
+ }
/*
* We didn't find the subvol, likely because it was
@@ -7267,8 +7272,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
* block from being modified, and we'll just bail for
* each subsequent pass.
*/
- if (ret == -ENOENT)
- ret = btrfs_pin_extent_for_log_replay(trans, log->node);
+ ret = btrfs_pin_extent_for_log_replay(trans, log->node);
btrfs_put_root(log);
if (!ret)
--
2.47.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] btrfs: abort transaction during log replay if walk_log_tree() failed
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
2025-05-21 17:44 ` [PATCH 1/4] btrfs: unfold transaction aborts when replaying log trees fdmanana
@ 2025-05-21 17:44 ` fdmanana
2025-05-21 17:44 ` [PATCH 3/4] btrfs: remove redundant path release when replaying a log tree fdmanana
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: fdmanana @ 2025-05-21 17:44 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
If we failed walking a log tree during replay, we have a missing
transaction abort to prevent committing a transaction where we didn't
fully replay all the changes from a log tree and therefore can leave the
respective subvolume tree in some incosistent state. So add the missing
transaction abort.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c1c4b8327229..730d67dba58c 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7283,11 +7283,14 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
wc.replay_dest->log_root = log;
ret = btrfs_record_root_in_trans(trans, wc.replay_dest);
- if (ret)
+ if (ret) {
/* The loop needs to continue due to the root refs */
btrfs_abort_transaction(trans, ret);
- else
+ } else {
ret = walk_log_tree(trans, log, &wc);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
+ }
if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
ret = fixup_inode_link_counts(trans, wc.replay_dest,
--
2.47.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] btrfs: remove redundant path release when replaying a log tree
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
2025-05-21 17:44 ` [PATCH 1/4] btrfs: unfold transaction aborts when replaying log trees fdmanana
2025-05-21 17:44 ` [PATCH 2/4] btrfs: abort transaction during log replay if walk_log_tree() failed fdmanana
@ 2025-05-21 17:44 ` fdmanana
2025-05-21 17:44 ` [PATCH 4/4] btrfs: simplify error detection flow during log replay fdmanana
2025-05-22 21:22 ` [PATCH 0/4] btrfs: some cleanups for the log tree replay code Qu Wenruo
4 siblings, 0 replies; 6+ messages in thread
From: fdmanana @ 2025-05-21 17:44 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
There's no need to call btrfs_release_path() before calling
btrfs_init_root_free_objectid() as we have released the path already at
the top of the loop and the previous call to fixup_inode_link_counts()
also releases the path. So remove it to simplify the code.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 730d67dba58c..ca2a2ee3c5f1 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7302,8 +7302,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
struct btrfs_root *root = wc.replay_dest;
- btrfs_release_path(path);
-
/*
* We have just replayed everything, and the highest
* objectid of fs roots probably has changed in case
--
2.47.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] btrfs: simplify error detection flow during log replay
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
` (2 preceding siblings ...)
2025-05-21 17:44 ` [PATCH 3/4] btrfs: remove redundant path release when replaying a log tree fdmanana
@ 2025-05-21 17:44 ` fdmanana
2025-05-22 21:22 ` [PATCH 0/4] btrfs: some cleanups for the log tree replay code Qu Wenruo
4 siblings, 0 replies; 6+ messages in thread
From: fdmanana @ 2025-05-21 17:44 UTC (permalink / raw)
To: linux-btrfs
From: Filipe Manana <fdmanana@suse.com>
We have this fuzzy logic at btrfs_recover_log_trees() where we don't
abort the transaction and exit immediately after each function call that
returned an error, and instead have if-then-else logic or check if the
previous function call returned success before calling the next function.
Make the flow more straighforward by immediately aborting the transaction
and exiting after each function call failure. This also allows to avoid
two consecutive if statements that test the same conditions:
if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
(...)
}
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/tree-log.c | 53 +++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 24 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index ca2a2ee3c5f1..0d5b79402312 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7192,8 +7192,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
struct btrfs_path *path;
struct btrfs_trans_handle *trans;
struct btrfs_key key;
- struct btrfs_key found_key;
- struct btrfs_root *log;
struct btrfs_fs_info *fs_info = log_root_tree->fs_info;
struct walk_control wc = {
.process_func = process_one_buffer,
@@ -7227,6 +7225,9 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
key.offset = (u64)-1;
while (1) {
+ struct btrfs_root *log;
+ struct btrfs_key found_key;
+
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
if (ret < 0) {
@@ -7255,6 +7256,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
true);
if (IS_ERR(wc.replay_dest)) {
ret = PTR_ERR(wc.replay_dest);
+ wc.replay_dest = NULL;
if (ret != -ENOENT) {
btrfs_put_root(log);
btrfs_abort_transaction(trans, ret);
@@ -7273,35 +7275,35 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
* each subsequent pass.
*/
ret = btrfs_pin_extent_for_log_replay(trans, log->node);
- btrfs_put_root(log);
-
- if (!ret)
- goto next;
- btrfs_abort_transaction(trans, ret);
- goto error;
+ if (ret) {
+ btrfs_put_root(log);
+ btrfs_abort_transaction(trans, ret);
+ goto error;
+ }
+ goto next;
}
wc.replay_dest->log_root = log;
ret = btrfs_record_root_in_trans(trans, wc.replay_dest);
if (ret) {
- /* The loop needs to continue due to the root refs */
btrfs_abort_transaction(trans, ret);
- } else {
- ret = walk_log_tree(trans, log, &wc);
- if (ret)
- btrfs_abort_transaction(trans, ret);
+ goto next;
}
- if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
- ret = fixup_inode_link_counts(trans, wc.replay_dest,
- path);
- if (ret)
- btrfs_abort_transaction(trans, ret);
+ ret = walk_log_tree(trans, log, &wc);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto next;
}
- if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
+ if (wc.stage == LOG_WALK_REPLAY_ALL) {
struct btrfs_root *root = wc.replay_dest;
+ ret = fixup_inode_link_counts(trans, wc.replay_dest, path);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto next;
+ }
/*
* We have just replayed everything, and the highest
* objectid of fs roots probably has changed in case
@@ -7311,17 +7313,20 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
* could only happen during mount.
*/
ret = btrfs_init_root_free_objectid(root);
- if (ret)
+ if (ret) {
btrfs_abort_transaction(trans, ret);
+ goto next;
+ }
+ }
+next:
+ if (wc.replay_dest) {
+ wc.replay_dest->log_root = NULL;
+ btrfs_put_root(wc.replay_dest);
}
-
- wc.replay_dest->log_root = NULL;
- btrfs_put_root(wc.replay_dest);
btrfs_put_root(log);
if (ret)
goto error;
-next:
if (found_key.offset == 0)
break;
key.offset = found_key.offset - 1;
--
2.47.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] btrfs: some cleanups for the log tree replay code
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
` (3 preceding siblings ...)
2025-05-21 17:44 ` [PATCH 4/4] btrfs: simplify error detection flow during log replay fdmanana
@ 2025-05-22 21:22 ` Qu Wenruo
4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2025-05-22 21:22 UTC (permalink / raw)
To: fdmanana, linux-btrfs
在 2025/5/22 03:14, fdmanana@kernel.org 写道:
> From: Filipe Manana <fdmanana@suse.com>
>
> A set of trivial cleanups after running into a bug I'm debugging where
> replaying directory deletes is failing. Details in the change logs.
Reviewed-by: Qu Wenruo <wqu@suse.com>
Thanks,
Qu
>
> Filipe Manana (4):
> btrfs: unfold transaction aborts when replaying log trees
> btrfs: abort transaction during log replay if walk_log_tree() failed
> btrfs: remove redundant path release when replaying a log tree
> btrfs: simplify error detection flow during log replay
>
> fs/btrfs/tree-log.c | 64 ++++++++++++++++++++++++++-------------------
> 1 file changed, 37 insertions(+), 27 deletions(-)
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-05-22 21:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-21 17:44 [PATCH 0/4] btrfs: some cleanups for the log tree replay code fdmanana
2025-05-21 17:44 ` [PATCH 1/4] btrfs: unfold transaction aborts when replaying log trees fdmanana
2025-05-21 17:44 ` [PATCH 2/4] btrfs: abort transaction during log replay if walk_log_tree() failed fdmanana
2025-05-21 17:44 ` [PATCH 3/4] btrfs: remove redundant path release when replaying a log tree fdmanana
2025-05-21 17:44 ` [PATCH 4/4] btrfs: simplify error detection flow during log replay fdmanana
2025-05-22 21:22 ` [PATCH 0/4] btrfs: some cleanups for the log tree replay code Qu Wenruo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox