diff options
author | Dave Chinner <dchinner@redhat.com> | 2014-09-28 19:45:32 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-09-28 19:45:32 -0400 |
commit | 88b863db97a18a04c90ebd57d84e1b7863114dcb (patch) | |
tree | 785d344f08359851fe68ce952b939f7415ba92f6 /fs/xfs/xfs_log_recover.c | |
parent | e9131e50f9d0a632e3011d73f283ba69be0cc682 (diff) |
xfs: fix double free in xlog_recover_commit_trans
When an error occurs during buffer submission in
xlog_recover_commit_trans(), we free the trans structure twice. Fix
it by only freeing the structure in the caller regardless of the
success or failure of the function.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 6d1c78378c31..89574ff2566e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -3528,8 +3528,6 @@ out: | |||
3528 | if (!list_empty(&done_list)) | 3528 | if (!list_empty(&done_list)) |
3529 | list_splice_init(&done_list, &trans->r_itemq); | 3529 | list_splice_init(&done_list, &trans->r_itemq); |
3530 | 3530 | ||
3531 | xlog_recover_free_trans(trans); | ||
3532 | |||
3533 | error2 = xfs_buf_delwri_submit(&buffer_list); | 3531 | error2 = xfs_buf_delwri_submit(&buffer_list); |
3534 | return error ? error : error2; | 3532 | return error ? error : error2; |
3535 | } | 3533 | } |
@@ -3554,6 +3552,10 @@ xlog_recovery_process_trans( | |||
3554 | if (flags & XLOG_WAS_CONT_TRANS) | 3552 | if (flags & XLOG_WAS_CONT_TRANS) |
3555 | flags &= ~XLOG_CONTINUE_TRANS; | 3553 | flags &= ~XLOG_CONTINUE_TRANS; |
3556 | 3554 | ||
3555 | /* | ||
3556 | * Callees must not free the trans structure. We'll decide if we need to | ||
3557 | * free it or not based on the operation being done and it's result. | ||
3558 | */ | ||
3557 | switch (flags) { | 3559 | switch (flags) { |
3558 | /* expected flag values */ | 3560 | /* expected flag values */ |
3559 | case 0: | 3561 | case 0: |
@@ -3565,6 +3567,8 @@ xlog_recovery_process_trans( | |||
3565 | break; | 3567 | break; |
3566 | case XLOG_COMMIT_TRANS: | 3568 | case XLOG_COMMIT_TRANS: |
3567 | error = xlog_recover_commit_trans(log, trans, pass); | 3569 | error = xlog_recover_commit_trans(log, trans, pass); |
3570 | /* success or fail, we are now done with this transaction. */ | ||
3571 | freeit = true; | ||
3568 | break; | 3572 | break; |
3569 | 3573 | ||
3570 | /* unexpected flag values */ | 3574 | /* unexpected flag values */ |