@@ -226,21 +226,32 @@ int btrfs_tree_mod_log_insert_key(struct extent_buffer *eb, int slot,
226226 enum btrfs_mod_log_op op )
227227{
228228 struct tree_mod_elem * tm ;
229- int ret ;
229+ int ret = 0 ;
230230
231231 if (!tree_mod_need_log (eb -> fs_info , eb ))
232232 return 0 ;
233233
234234 tm = alloc_tree_mod_elem (eb , slot , op );
235235 if (!tm )
236- return - ENOMEM ;
236+ ret = - ENOMEM ;
237237
238238 if (tree_mod_dont_log (eb -> fs_info , eb )) {
239239 kfree (tm );
240+ /*
241+ * Don't error if we failed to allocate memory because we don't
242+ * need to log.
243+ */
240244 return 0 ;
245+ } else if (ret != 0 ) {
246+ /*
247+ * We previously failed to allocate memory and we need to log,
248+ * so we have to fail.
249+ */
250+ goto out_unlock ;
241251 }
242252
243253 ret = tree_mod_log_insert (eb -> fs_info , tm );
254+ out_unlock :
244255 write_unlock (& eb -> fs_info -> tree_mod_log_lock );
245256 if (ret )
246257 kfree (tm );
@@ -282,29 +293,45 @@ int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb,
282293 return 0 ;
283294
284295 tm_list = kcalloc (nr_items , sizeof (struct tree_mod_elem * ), GFP_NOFS );
285- if (!tm_list )
286- return - ENOMEM ;
296+ if (!tm_list ) {
297+ ret = - ENOMEM ;
298+ goto lock ;
299+ }
287300
288301 tm = tree_mod_log_alloc_move (eb , dst_slot , src_slot , nr_items );
289302 if (IS_ERR (tm )) {
290303 ret = PTR_ERR (tm );
291304 tm = NULL ;
292- goto free_tms ;
305+ goto lock ;
293306 }
294307
295308 for (i = 0 ; i + dst_slot < src_slot && i < nr_items ; i ++ ) {
296309 tm_list [i ] = alloc_tree_mod_elem (eb , i + dst_slot ,
297310 BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING );
298311 if (!tm_list [i ]) {
299312 ret = - ENOMEM ;
300- goto free_tms ;
313+ goto lock ;
301314 }
302315 }
303316
304- if (tree_mod_dont_log (eb -> fs_info , eb ))
317+ lock :
318+ if (tree_mod_dont_log (eb -> fs_info , eb )) {
319+ /*
320+ * Don't error if we failed to allocate memory because we don't
321+ * need to log.
322+ */
323+ ret = 0 ;
305324 goto free_tms ;
325+ }
306326 locked = true;
307327
328+ /*
329+ * We previously failed to allocate memory and we need to log, so we
330+ * have to fail.
331+ */
332+ if (ret != 0 )
333+ goto free_tms ;
334+
308335 /*
309336 * When we override something during the move, we log these removals.
310337 * This can only happen when we move towards the beginning of the
@@ -325,10 +352,12 @@ int btrfs_tree_mod_log_insert_move(struct extent_buffer *eb,
325352 return 0 ;
326353
327354free_tms :
328- for (i = 0 ; i < nr_items ; i ++ ) {
329- if (tm_list [i ] && !RB_EMPTY_NODE (& tm_list [i ]-> node ))
330- rb_erase (& tm_list [i ]-> node , & eb -> fs_info -> tree_mod_log );
331- kfree (tm_list [i ]);
355+ if (tm_list ) {
356+ for (i = 0 ; i < nr_items ; i ++ ) {
357+ if (tm_list [i ] && !RB_EMPTY_NODE (& tm_list [i ]-> node ))
358+ rb_erase (& tm_list [i ]-> node , & eb -> fs_info -> tree_mod_log );
359+ kfree (tm_list [i ]);
360+ }
332361 }
333362 if (locked )
334363 write_unlock (& eb -> fs_info -> tree_mod_log_lock );
@@ -378,22 +407,22 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root,
378407 GFP_NOFS );
379408 if (!tm_list ) {
380409 ret = - ENOMEM ;
381- goto free_tms ;
410+ goto lock ;
382411 }
383412 for (i = 0 ; i < nritems ; i ++ ) {
384413 tm_list [i ] = alloc_tree_mod_elem (old_root , i ,
385414 BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING );
386415 if (!tm_list [i ]) {
387416 ret = - ENOMEM ;
388- goto free_tms ;
417+ goto lock ;
389418 }
390419 }
391420 }
392421
393422 tm = kzalloc (sizeof (* tm ), GFP_NOFS );
394423 if (!tm ) {
395424 ret = - ENOMEM ;
396- goto free_tms ;
425+ goto lock ;
397426 }
398427
399428 tm -> logical = new_root -> start ;
@@ -402,14 +431,28 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root,
402431 tm -> generation = btrfs_header_generation (old_root );
403432 tm -> op = BTRFS_MOD_LOG_ROOT_REPLACE ;
404433
405- if (tree_mod_dont_log (fs_info , NULL ))
434+ lock :
435+ if (tree_mod_dont_log (fs_info , NULL )) {
436+ /*
437+ * Don't error if we failed to allocate memory because we don't
438+ * need to log.
439+ */
440+ ret = 0 ;
406441 goto free_tms ;
442+ } else if (ret != 0 ) {
443+ /*
444+ * We previously failed to allocate memory and we need to log,
445+ * so we have to fail.
446+ */
447+ goto out_unlock ;
448+ }
407449
408450 if (tm_list )
409451 ret = tree_mod_log_free_eb (fs_info , tm_list , nritems );
410452 if (!ret )
411453 ret = tree_mod_log_insert (fs_info , tm );
412454
455+ out_unlock :
413456 write_unlock (& fs_info -> tree_mod_log_lock );
414457 if (ret )
415458 goto free_tms ;
@@ -501,7 +544,8 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
501544 struct btrfs_fs_info * fs_info = dst -> fs_info ;
502545 int ret = 0 ;
503546 struct tree_mod_elem * * tm_list = NULL ;
504- struct tree_mod_elem * * tm_list_add , * * tm_list_rem ;
547+ struct tree_mod_elem * * tm_list_add = NULL ;
548+ struct tree_mod_elem * * tm_list_rem = NULL ;
505549 int i ;
506550 bool locked = false;
507551 struct tree_mod_elem * dst_move_tm = NULL ;
@@ -517,16 +561,18 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
517561
518562 tm_list = kcalloc (nr_items * 2 , sizeof (struct tree_mod_elem * ),
519563 GFP_NOFS );
520- if (!tm_list )
521- return - ENOMEM ;
564+ if (!tm_list ) {
565+ ret = - ENOMEM ;
566+ goto lock ;
567+ }
522568
523569 if (dst_move_nr_items ) {
524570 dst_move_tm = tree_mod_log_alloc_move (dst , dst_offset + nr_items ,
525571 dst_offset , dst_move_nr_items );
526572 if (IS_ERR (dst_move_tm )) {
527573 ret = PTR_ERR (dst_move_tm );
528574 dst_move_tm = NULL ;
529- goto free_tms ;
575+ goto lock ;
530576 }
531577 }
532578 if (src_move_nr_items ) {
@@ -536,7 +582,7 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
536582 if (IS_ERR (src_move_tm )) {
537583 ret = PTR_ERR (src_move_tm );
538584 src_move_tm = NULL ;
539- goto free_tms ;
585+ goto lock ;
540586 }
541587 }
542588
@@ -547,21 +593,35 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
547593 BTRFS_MOD_LOG_KEY_REMOVE );
548594 if (!tm_list_rem [i ]) {
549595 ret = - ENOMEM ;
550- goto free_tms ;
596+ goto lock ;
551597 }
552598
553599 tm_list_add [i ] = alloc_tree_mod_elem (dst , i + dst_offset ,
554600 BTRFS_MOD_LOG_KEY_ADD );
555601 if (!tm_list_add [i ]) {
556602 ret = - ENOMEM ;
557- goto free_tms ;
603+ goto lock ;
558604 }
559605 }
560606
561- if (tree_mod_dont_log (fs_info , NULL ))
607+ lock :
608+ if (tree_mod_dont_log (fs_info , NULL )) {
609+ /*
610+ * Don't error if we failed to allocate memory because we don't
611+ * need to log.
612+ */
613+ ret = 0 ;
562614 goto free_tms ;
615+ }
563616 locked = true;
564617
618+ /*
619+ * We previously failed to allocate memory and we need to log, so we
620+ * have to fail.
621+ */
622+ if (ret != 0 )
623+ goto free_tms ;
624+
565625 if (dst_move_tm ) {
566626 ret = tree_mod_log_insert (fs_info , dst_move_tm );
567627 if (ret )
@@ -593,10 +653,12 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst,
593653 if (src_move_tm && !RB_EMPTY_NODE (& src_move_tm -> node ))
594654 rb_erase (& src_move_tm -> node , & fs_info -> tree_mod_log );
595655 kfree (src_move_tm );
596- for (i = 0 ; i < nr_items * 2 ; i ++ ) {
597- if (tm_list [i ] && !RB_EMPTY_NODE (& tm_list [i ]-> node ))
598- rb_erase (& tm_list [i ]-> node , & fs_info -> tree_mod_log );
599- kfree (tm_list [i ]);
656+ if (tm_list ) {
657+ for (i = 0 ; i < nr_items * 2 ; i ++ ) {
658+ if (tm_list [i ] && !RB_EMPTY_NODE (& tm_list [i ]-> node ))
659+ rb_erase (& tm_list [i ]-> node , & fs_info -> tree_mod_log );
660+ kfree (tm_list [i ]);
661+ }
600662 }
601663 if (locked )
602664 write_unlock (& fs_info -> tree_mod_log_lock );
@@ -617,22 +679,38 @@ int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb)
617679
618680 nritems = btrfs_header_nritems (eb );
619681 tm_list = kcalloc (nritems , sizeof (struct tree_mod_elem * ), GFP_NOFS );
620- if (!tm_list )
621- return - ENOMEM ;
682+ if (!tm_list ) {
683+ ret = - ENOMEM ;
684+ goto lock ;
685+ }
622686
623687 for (i = 0 ; i < nritems ; i ++ ) {
624688 tm_list [i ] = alloc_tree_mod_elem (eb , i ,
625689 BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING );
626690 if (!tm_list [i ]) {
627691 ret = - ENOMEM ;
628- goto free_tms ;
692+ goto lock ;
629693 }
630694 }
631695
632- if (tree_mod_dont_log (eb -> fs_info , eb ))
696+ lock :
697+ if (tree_mod_dont_log (eb -> fs_info , eb )) {
698+ /*
699+ * Don't error if we failed to allocate memory because we don't
700+ * need to log.
701+ */
702+ ret = 0 ;
633703 goto free_tms ;
704+ } else if (ret != 0 ) {
705+ /*
706+ * We previously failed to allocate memory and we need to log,
707+ * so we have to fail.
708+ */
709+ goto out_unlock ;
710+ }
634711
635712 ret = tree_mod_log_free_eb (eb -> fs_info , tm_list , nritems );
713+ out_unlock :
636714 write_unlock (& eb -> fs_info -> tree_mod_log_lock );
637715 if (ret )
638716 goto free_tms ;
@@ -641,9 +719,11 @@ int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb)
641719 return 0 ;
642720
643721free_tms :
644- for (i = 0 ; i < nritems ; i ++ )
645- kfree (tm_list [i ]);
646- kfree (tm_list );
722+ if (tm_list ) {
723+ for (i = 0 ; i < nritems ; i ++ )
724+ kfree (tm_list [i ]);
725+ kfree (tm_list );
726+ }
647727
648728 return ret ;
649729}
0 commit comments