Skip to content

Commit efa44fc

Browse files
fdmananakdave
authored andcommitted
btrfs: add and use a log root field to struct walk_control
Instead of passing an extra log root parameter for the log tree walk functions and callbacks, add the log tree to struct walk_control and make those functions and callbacks extract the log root from that structure, reducing the number of parameters. This also simplifies further upcoming changes to report log tree replay failures. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 60ac802 commit efa44fc

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

fs/btrfs/tree-log.c

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ struct walk_control {
336336
*/
337337
struct btrfs_root *root;
338338

339+
/* The log tree we are currently processing (not NULL for any stage). */
340+
struct btrfs_root *log;
341+
339342
/* the trans handle for the current replay */
340343
struct btrfs_trans_handle *trans;
341344

@@ -344,17 +347,17 @@ struct walk_control {
344347
* passed in, and it must be checked or read if you need the data
345348
* inside it
346349
*/
347-
int (*process_func)(struct btrfs_root *log, struct extent_buffer *eb,
350+
int (*process_func)(struct extent_buffer *eb,
348351
struct walk_control *wc, u64 gen, int level);
349352
};
350353

351354
/*
352355
* process_func used to pin down extents, write them or wait on them
353356
*/
354-
static int process_one_buffer(struct btrfs_root *log,
355-
struct extent_buffer *eb,
357+
static int process_one_buffer(struct extent_buffer *eb,
356358
struct walk_control *wc, u64 gen, int level)
357359
{
360+
struct btrfs_root *log = wc->log;
358361
struct btrfs_trans_handle *trans = wc->trans;
359362
struct btrfs_fs_info *fs_info = log->fs_info;
360363
int ret = 0;
@@ -2569,7 +2572,7 @@ static noinline int replay_dir_deletes(struct btrfs_trans_handle *trans,
25692572
* only in the log (references come from either directory items or inode
25702573
* back refs).
25712574
*/
2572-
static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
2575+
static int replay_one_buffer(struct extent_buffer *eb,
25732576
struct walk_control *wc, u64 gen, int level)
25742577
{
25752578
int nritems;
@@ -2579,6 +2582,7 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
25792582
};
25802583
struct btrfs_path *path;
25812584
struct btrfs_root *root = wc->root;
2585+
struct btrfs_root *log = wc->log;
25822586
struct btrfs_trans_handle *trans = wc->trans;
25832587
struct btrfs_key key;
25842588
int i;
@@ -2779,11 +2783,10 @@ static int clean_log_buffer(struct btrfs_trans_handle *trans,
27792783
}
27802784

27812785
static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
2782-
struct btrfs_root *log,
27832786
struct btrfs_path *path, int *level,
27842787
struct walk_control *wc)
27852788
{
2786-
struct btrfs_fs_info *fs_info = log->fs_info;
2789+
struct btrfs_fs_info *fs_info = wc->log->fs_info;
27872790
u64 bytenr;
27882791
u64 ptr_gen;
27892792
struct extent_buffer *next;
@@ -2821,7 +2824,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
28212824
}
28222825

28232826
if (*level == 1) {
2824-
ret = wc->process_func(log, next, wc, ptr_gen, *level - 1);
2827+
ret = wc->process_func(next, wc, ptr_gen, *level - 1);
28252828
if (ret) {
28262829
free_extent_buffer(next);
28272830
return ret;
@@ -2872,7 +2875,6 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
28722875
}
28732876

28742877
static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
2875-
struct btrfs_root *log,
28762878
struct btrfs_path *path, int *level,
28772879
struct walk_control *wc)
28782880
{
@@ -2888,7 +2890,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
28882890
WARN_ON(*level == 0);
28892891
return 0;
28902892
} else {
2891-
ret = wc->process_func(log, path->nodes[*level], wc,
2893+
ret = wc->process_func(path->nodes[*level], wc,
28922894
btrfs_header_generation(path->nodes[*level]),
28932895
*level);
28942896
if (ret)
@@ -2912,9 +2914,9 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
29122914
* the tree freeing any blocks that have a ref count of zero after being
29132915
* decremented.
29142916
*/
2915-
static int walk_log_tree(struct btrfs_trans_handle *trans,
2916-
struct btrfs_root *log, struct walk_control *wc)
2917+
static int walk_log_tree(struct btrfs_trans_handle *trans, struct walk_control *wc)
29172918
{
2919+
struct btrfs_root *log = wc->log;
29182920
int ret = 0;
29192921
int wret;
29202922
int level;
@@ -2932,15 +2934,15 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
29322934
path->slots[level] = 0;
29332935

29342936
while (1) {
2935-
wret = walk_down_log_tree(trans, log, path, &level, wc);
2937+
wret = walk_down_log_tree(trans, path, &level, wc);
29362938
if (wret > 0)
29372939
break;
29382940
if (wret < 0) {
29392941
ret = wret;
29402942
goto out;
29412943
}
29422944

2943-
wret = walk_up_log_tree(trans, log, path, &level, wc);
2945+
wret = walk_up_log_tree(trans, path, &level, wc);
29442946
if (wret > 0)
29452947
break;
29462948
if (wret < 0) {
@@ -2951,7 +2953,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
29512953

29522954
/* was the root node processed? if not, catch it here */
29532955
if (path->nodes[orig_level]) {
2954-
ret = wc->process_func(log, path->nodes[orig_level], wc,
2956+
ret = wc->process_func(path->nodes[orig_level], wc,
29552957
btrfs_header_generation(path->nodes[orig_level]),
29562958
orig_level);
29572959
if (ret)
@@ -3423,11 +3425,12 @@ static void free_log_tree(struct btrfs_trans_handle *trans,
34233425
int ret;
34243426
struct walk_control wc = {
34253427
.free = true,
3426-
.process_func = process_one_buffer
3428+
.process_func = process_one_buffer,
3429+
.log = log,
34273430
};
34283431

34293432
if (log->node) {
3430-
ret = walk_log_tree(trans, log, &wc);
3433+
ret = walk_log_tree(trans, &wc);
34313434
if (ret) {
34323435
/*
34333436
* We weren't able to traverse the entire log tree, the
@@ -7441,8 +7444,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
74417444

74427445
wc.trans = trans;
74437446
wc.pin = true;
7447+
wc.log = log_root_tree;
74447448

7445-
ret = walk_log_tree(trans, log_root_tree, &wc);
7449+
ret = walk_log_tree(trans, &wc);
7450+
wc.log = NULL;
74467451
if (ret) {
74477452
btrfs_abort_transaction(trans, ret);
74487453
goto error;
@@ -7454,7 +7459,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
74547459
key.offset = (u64)-1;
74557460

74567461
while (1) {
7457-
struct btrfs_root *log;
74587462
struct btrfs_key found_key;
74597463

74607464
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
@@ -7474,9 +7478,10 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
74747478
if (found_key.objectid != BTRFS_TREE_LOG_OBJECTID)
74757479
break;
74767480

7477-
log = btrfs_read_tree_root(log_root_tree, &found_key);
7478-
if (IS_ERR(log)) {
7479-
ret = PTR_ERR(log);
7481+
wc.log = btrfs_read_tree_root(log_root_tree, &found_key);
7482+
if (IS_ERR(wc.log)) {
7483+
ret = PTR_ERR(wc.log);
7484+
wc.log = NULL;
74807485
btrfs_abort_transaction(trans, ret);
74817486
goto error;
74827487
}
@@ -7486,7 +7491,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
74867491
ret = PTR_ERR(wc.root);
74877492
wc.root = NULL;
74887493
if (ret != -ENOENT) {
7489-
btrfs_put_root(log);
7494+
btrfs_put_root(wc.log);
7495+
wc.log = NULL;
74907496
btrfs_abort_transaction(trans, ret);
74917497
goto error;
74927498
}
@@ -7502,23 +7508,24 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
75027508
* block from being modified, and we'll just bail for
75037509
* each subsequent pass.
75047510
*/
7505-
ret = btrfs_pin_extent_for_log_replay(trans, log->node);
7511+
ret = btrfs_pin_extent_for_log_replay(trans, wc.log->node);
75067512
if (ret) {
7507-
btrfs_put_root(log);
7513+
btrfs_put_root(wc.log);
7514+
wc.log = NULL;
75087515
btrfs_abort_transaction(trans, ret);
75097516
goto error;
75107517
}
75117518
goto next;
75127519
}
75137520

7514-
wc.root->log_root = log;
7521+
wc.root->log_root = wc.log;
75157522
ret = btrfs_record_root_in_trans(trans, wc.root);
75167523
if (ret) {
75177524
btrfs_abort_transaction(trans, ret);
75187525
goto next;
75197526
}
75207527

7521-
ret = walk_log_tree(trans, log, &wc);
7528+
ret = walk_log_tree(trans, &wc);
75227529
if (ret) {
75237530
btrfs_abort_transaction(trans, ret);
75247531
goto next;
@@ -7551,7 +7558,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
75517558
wc.root->log_root = NULL;
75527559
btrfs_put_root(wc.root);
75537560
}
7554-
btrfs_put_root(log);
7561+
btrfs_put_root(wc.log);
7562+
wc.log = NULL;
75557563

75567564
if (ret)
75577565
goto error;

0 commit comments

Comments
 (0)