@@ -2576,42 +2576,40 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
2576
2576
2577
2577
/* Split the expression string at the root operator */
2578
2578
if (!sep )
2579
- goto free ;
2579
+ return ERR_PTR (- EINVAL );
2580
+
2580
2581
* sep = '\0' ;
2581
2582
operand1_str = str ;
2582
2583
str = sep + 1 ;
2583
2584
2584
2585
/* Binary operator requires both operands */
2585
2586
if (* operand1_str == '\0' || * str == '\0' )
2586
- goto free ;
2587
+ return ERR_PTR ( - EINVAL ) ;
2587
2588
2588
2589
operand_flags = 0 ;
2589
2590
2590
2591
/* LHS of string is an expression e.g. a+b in a+b+c */
2591
2592
operand1 = parse_expr (hist_data , file , operand1_str , operand_flags , NULL , n_subexprs );
2592
- if (IS_ERR (operand1 )) {
2593
- ret = PTR_ERR (operand1 );
2594
- operand1 = NULL ;
2595
- goto free ;
2596
- }
2593
+ if (IS_ERR (operand1 ))
2594
+ return ERR_CAST (operand1 );
2595
+
2597
2596
if (operand1 -> flags & HIST_FIELD_FL_STRING ) {
2598
2597
hist_err (file -> tr , HIST_ERR_INVALID_STR_OPERAND , errpos (operand1_str ));
2599
2598
ret = - EINVAL ;
2600
- goto free ;
2599
+ goto free_op1 ;
2601
2600
}
2602
2601
2603
2602
/* RHS of string is another expression e.g. c in a+b+c */
2604
2603
operand_flags = 0 ;
2605
2604
operand2 = parse_expr (hist_data , file , str , operand_flags , NULL , n_subexprs );
2606
2605
if (IS_ERR (operand2 )) {
2607
2606
ret = PTR_ERR (operand2 );
2608
- operand2 = NULL ;
2609
- goto free ;
2607
+ goto free_op1 ;
2610
2608
}
2611
2609
if (operand2 -> flags & HIST_FIELD_FL_STRING ) {
2612
2610
hist_err (file -> tr , HIST_ERR_INVALID_STR_OPERAND , errpos (str ));
2613
2611
ret = - EINVAL ;
2614
- goto free ;
2612
+ goto free_operands ;
2615
2613
}
2616
2614
2617
2615
switch (field_op ) {
@@ -2629,12 +2627,12 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
2629
2627
break ;
2630
2628
default :
2631
2629
ret = - EINVAL ;
2632
- goto free ;
2630
+ goto free_operands ;
2633
2631
}
2634
2632
2635
2633
ret = check_expr_operands (file -> tr , operand1 , operand2 , & var1 , & var2 );
2636
2634
if (ret )
2637
- goto free ;
2635
+ goto free_operands ;
2638
2636
2639
2637
operand_flags = var1 ? var1 -> flags : operand1 -> flags ;
2640
2638
operand2_flags = var2 ? var2 -> flags : operand2 -> flags ;
@@ -2653,12 +2651,13 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
2653
2651
expr = create_hist_field (hist_data , NULL , flags , var_name );
2654
2652
if (!expr ) {
2655
2653
ret = - ENOMEM ;
2656
- goto free ;
2654
+ goto free_operands ;
2657
2655
}
2658
2656
2659
2657
operand1 -> read_once = true;
2660
2658
operand2 -> read_once = true;
2661
2659
2660
+ /* The operands are now owned and free'd by 'expr' */
2662
2661
expr -> operands [0 ] = operand1 ;
2663
2662
expr -> operands [1 ] = operand2 ;
2664
2663
@@ -2669,7 +2668,7 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
2669
2668
if (!divisor ) {
2670
2669
hist_err (file -> tr , HIST_ERR_DIVISION_BY_ZERO , errpos (str ));
2671
2670
ret = - EDOM ;
2672
- goto free ;
2671
+ goto free_expr ;
2673
2672
}
2674
2673
2675
2674
/*
@@ -2709,18 +2708,22 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data,
2709
2708
expr -> type = kstrdup_const (operand1 -> type , GFP_KERNEL );
2710
2709
if (!expr -> type ) {
2711
2710
ret = - ENOMEM ;
2712
- goto free ;
2711
+ goto free_expr ;
2713
2712
}
2714
2713
2715
2714
expr -> name = expr_str (expr , 0 );
2716
2715
}
2717
2716
2718
2717
return expr ;
2719
- free :
2720
- destroy_hist_field ( operand1 , 0 );
2718
+
2719
+ free_operands :
2721
2720
destroy_hist_field (operand2 , 0 );
2722
- destroy_hist_field (expr , 0 );
2721
+ free_op1 :
2722
+ destroy_hist_field (operand1 , 0 );
2723
+ return ERR_PTR (ret );
2723
2724
2725
+ free_expr :
2726
+ destroy_hist_field (expr , 0 );
2724
2727
return ERR_PTR (ret );
2725
2728
}
2726
2729
0 commit comments