@@ -7546,7 +7546,7 @@ static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
7546
7546
* returns the key for the extent through ins, and a tree buffer for
7547
7547
* the first block of the extent through buf.
7548
7548
*
7549
- * returns the tree buffer or NULL .
7549
+ * returns the tree buffer or an ERR_PTR on error .
7550
7550
*/
7551
7551
struct extent_buffer * btrfs_alloc_tree_block (struct btrfs_trans_handle * trans ,
7552
7552
struct btrfs_root * root ,
@@ -7557,6 +7557,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7557
7557
struct btrfs_key ins ;
7558
7558
struct btrfs_block_rsv * block_rsv ;
7559
7559
struct extent_buffer * buf ;
7560
+ struct btrfs_delayed_extent_op * extent_op ;
7560
7561
u64 flags = 0 ;
7561
7562
int ret ;
7562
7563
u32 blocksize = root -> nodesize ;
@@ -7577,13 +7578,14 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7577
7578
7578
7579
ret = btrfs_reserve_extent (root , blocksize , blocksize ,
7579
7580
empty_size , hint , & ins , 0 , 0 );
7580
- if (ret ) {
7581
- unuse_block_rsv (root -> fs_info , block_rsv , blocksize );
7582
- return ERR_PTR (ret );
7583
- }
7581
+ if (ret )
7582
+ goto out_unuse ;
7584
7583
7585
7584
buf = btrfs_init_new_buffer (trans , root , ins .objectid , level );
7586
- BUG_ON (IS_ERR (buf )); /* -ENOMEM */
7585
+ if (IS_ERR (buf )) {
7586
+ ret = PTR_ERR (buf );
7587
+ goto out_free_reserved ;
7588
+ }
7587
7589
7588
7590
if (root_objectid == BTRFS_TREE_RELOC_OBJECTID ) {
7589
7591
if (parent == 0 )
@@ -7593,9 +7595,11 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7593
7595
BUG_ON (parent > 0 );
7594
7596
7595
7597
if (root_objectid != BTRFS_TREE_LOG_OBJECTID ) {
7596
- struct btrfs_delayed_extent_op * extent_op ;
7597
7598
extent_op = btrfs_alloc_delayed_extent_op ();
7598
- BUG_ON (!extent_op ); /* -ENOMEM */
7599
+ if (!extent_op ) {
7600
+ ret = - ENOMEM ;
7601
+ goto out_free_buf ;
7602
+ }
7599
7603
if (key )
7600
7604
memcpy (& extent_op -> key , key , sizeof (extent_op -> key ));
7601
7605
else
@@ -7610,13 +7614,24 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7610
7614
extent_op -> level = level ;
7611
7615
7612
7616
ret = btrfs_add_delayed_tree_ref (root -> fs_info , trans ,
7613
- ins .objectid ,
7614
- ins .offset , parent , root_objectid ,
7615
- level , BTRFS_ADD_DELAYED_EXTENT ,
7616
- extent_op , 0 );
7617
- BUG_ON (ret ); /* -ENOMEM */
7617
+ ins .objectid , ins .offset ,
7618
+ parent , root_objectid , level ,
7619
+ BTRFS_ADD_DELAYED_EXTENT ,
7620
+ extent_op , 0 );
7621
+ if (ret )
7622
+ goto out_free_delayed ;
7618
7623
}
7619
7624
return buf ;
7625
+
7626
+ out_free_delayed :
7627
+ btrfs_free_delayed_extent_op (extent_op );
7628
+ out_free_buf :
7629
+ free_extent_buffer (buf );
7630
+ out_free_reserved :
7631
+ btrfs_free_reserved_extent (root , ins .objectid , ins .offset , 0 );
7632
+ out_unuse :
7633
+ unuse_block_rsv (root -> fs_info , block_rsv , blocksize );
7634
+ return ERR_PTR (ret );
7620
7635
}
7621
7636
7622
7637
struct walk_control {
0 commit comments