@@ -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
27812785static 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
28742877static 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