@@ -3021,9 +3021,6 @@ void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
30213021 cache -> rb_root = RB_ROOT ;
30223022 for (i = 0 ; i < BTRFS_MAX_LEVEL ; i ++ )
30233023 INIT_LIST_HEAD (& cache -> pending [i ]);
3024- INIT_LIST_HEAD (& cache -> changed );
3025- INIT_LIST_HEAD (& cache -> detached );
3026- INIT_LIST_HEAD (& cache -> leaves );
30273024 INIT_LIST_HEAD (& cache -> pending_edge );
30283025 INIT_LIST_HEAD (& cache -> useless_node );
30293026 cache -> fs_info = fs_info ;
@@ -3131,29 +3128,17 @@ void btrfs_backref_drop_node(struct btrfs_backref_cache *tree,
31313128void btrfs_backref_cleanup_node (struct btrfs_backref_cache * cache ,
31323129 struct btrfs_backref_node * node )
31333130{
3134- struct btrfs_backref_node * upper ;
31353131 struct btrfs_backref_edge * edge ;
31363132
31373133 if (!node )
31383134 return ;
31393135
3140- BUG_ON (!node -> lowest && !node -> detached );
31413136 while (!list_empty (& node -> upper )) {
31423137 edge = list_entry (node -> upper .next , struct btrfs_backref_edge ,
31433138 list [LOWER ]);
3144- upper = edge -> node [UPPER ];
31453139 list_del (& edge -> list [LOWER ]);
31463140 list_del (& edge -> list [UPPER ]);
31473141 btrfs_backref_free_edge (cache , edge );
3148-
3149- /*
3150- * Add the node to leaf node list if no other child block
3151- * cached.
3152- */
3153- if (list_empty (& upper -> lower )) {
3154- list_add_tail (& upper -> lower , & cache -> leaves );
3155- upper -> lowest = 1 ;
3156- }
31573142 }
31583143
31593144 btrfs_backref_drop_node (cache , node );
@@ -3165,33 +3150,13 @@ void btrfs_backref_cleanup_node(struct btrfs_backref_cache *cache,
31653150void btrfs_backref_release_cache (struct btrfs_backref_cache * cache )
31663151{
31673152 struct btrfs_backref_node * node ;
3168- int i ;
3169-
3170- while (!list_empty (& cache -> detached )) {
3171- node = list_entry (cache -> detached .next ,
3172- struct btrfs_backref_node , list );
3173- btrfs_backref_cleanup_node (cache , node );
3174- }
31753153
3176- while (!list_empty (& cache -> leaves )) {
3177- node = list_entry (cache -> leaves .next ,
3178- struct btrfs_backref_node , lower );
3154+ while ((node = rb_entry_safe (rb_first (& cache -> rb_root ),
3155+ struct btrfs_backref_node , rb_node )))
31793156 btrfs_backref_cleanup_node (cache , node );
3180- }
31813157
3182- for (i = 0 ; i < BTRFS_MAX_LEVEL ; i ++ ) {
3183- while (!list_empty (& cache -> pending [i ])) {
3184- node = list_first_entry (& cache -> pending [i ],
3185- struct btrfs_backref_node ,
3186- list );
3187- btrfs_backref_cleanup_node (cache , node );
3188- }
3189- }
31903158 ASSERT (list_empty (& cache -> pending_edge ));
31913159 ASSERT (list_empty (& cache -> useless_node ));
3192- ASSERT (list_empty (& cache -> changed ));
3193- ASSERT (list_empty (& cache -> detached ));
3194- ASSERT (RB_EMPTY_ROOT (& cache -> rb_root ));
31953160 ASSERT (!cache -> nr_nodes );
31963161 ASSERT (!cache -> nr_edges );
31973162}
@@ -3315,8 +3280,16 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
33153280 root = btrfs_get_fs_root (fs_info , ref_key -> offset , false);
33163281 if (IS_ERR (root ))
33173282 return PTR_ERR (root );
3318- if (!test_bit (BTRFS_ROOT_SHAREABLE , & root -> state ))
3319- cur -> cowonly = 1 ;
3283+
3284+ /*
3285+ * We shouldn't be using backref cache for non shareable roots, ASSERT
3286+ * for developers, return -EUCLEAN for users.
3287+ */
3288+ if (!test_bit (BTRFS_ROOT_SHAREABLE , & root -> state )) {
3289+ btrfs_put_root (root );
3290+ ASSERT (0 );
3291+ return - EUCLEAN ;
3292+ }
33203293
33213294 if (btrfs_root_level (& root -> root_item ) == cur -> level ) {
33223295 /* Tree root */
@@ -3402,8 +3375,20 @@ static int handle_indirect_tree_backref(struct btrfs_trans_handle *trans,
34023375 goto out ;
34033376 }
34043377 upper -> owner = btrfs_header_owner (eb );
3405- if (!test_bit (BTRFS_ROOT_SHAREABLE , & root -> state ))
3406- upper -> cowonly = 1 ;
3378+
3379+ /*
3380+ * We shouldn't be using backref cache for non shareable
3381+ * roots, ASSERT for developers, return -EUCLEAN for
3382+ * users.
3383+ */
3384+ if (!test_bit (BTRFS_ROOT_SHAREABLE , & root -> state )) {
3385+ btrfs_put_root (root );
3386+ btrfs_backref_free_edge (cache , edge );
3387+ btrfs_backref_free_node (cache , upper );
3388+ ASSERT (0 );
3389+ ret = - EUCLEAN ;
3390+ goto out ;
3391+ }
34073392
34083393 /*
34093394 * If we know the block isn't shared we can avoid
@@ -3594,15 +3579,11 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
35943579
35953580 ASSERT (start -> checked );
35963581
3597- /* Insert this node to cache if it's not COW-only */
3598- if (!start -> cowonly ) {
3599- rb_node = rb_simple_insert (& cache -> rb_root , start -> bytenr ,
3600- & start -> rb_node );
3601- if (rb_node )
3602- btrfs_backref_panic (cache -> fs_info , start -> bytenr ,
3603- - EEXIST );
3604- list_add_tail (& start -> lower , & cache -> leaves );
3605- }
3582+ rb_node = rb_simple_insert (& cache -> rb_root , start -> bytenr ,
3583+ & start -> rb_node );
3584+ if (rb_node )
3585+ btrfs_backref_panic (cache -> fs_info , start -> bytenr ,
3586+ - EEXIST );
36063587
36073588 /*
36083589 * Use breadth first search to iterate all related edges.
@@ -3641,11 +3622,6 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
36413622 * parents have already been linked.
36423623 */
36433624 if (!RB_EMPTY_NODE (& upper -> rb_node )) {
3644- if (upper -> lowest ) {
3645- list_del_init (& upper -> lower );
3646- upper -> lowest = 0 ;
3647- }
3648-
36493625 list_add_tail (& edge -> list [UPPER ], & upper -> lower );
36503626 continue ;
36513627 }
@@ -3656,23 +3632,14 @@ int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
36563632 return - EUCLEAN ;
36573633 }
36583634
3659- /* Sanity check, COW-only node has non-COW-only parent */
3660- if (start -> cowonly != upper -> cowonly ) {
3661- ASSERT (0 );
3635+ rb_node = rb_simple_insert (& cache -> rb_root , upper -> bytenr ,
3636+ & upper -> rb_node );
3637+ if (rb_node ) {
3638+ btrfs_backref_panic (cache -> fs_info ,
3639+ upper -> bytenr , - EEXIST );
36623640 return - EUCLEAN ;
36633641 }
36643642
3665- /* Only cache non-COW-only (subvolume trees) tree blocks */
3666- if (!upper -> cowonly ) {
3667- rb_node = rb_simple_insert (& cache -> rb_root , upper -> bytenr ,
3668- & upper -> rb_node );
3669- if (rb_node ) {
3670- btrfs_backref_panic (cache -> fs_info ,
3671- upper -> bytenr , - EEXIST );
3672- return - EUCLEAN ;
3673- }
3674- }
3675-
36763643 list_add_tail (& edge -> list [UPPER ], & upper -> lower );
36773644
36783645 /*
0 commit comments