xfs: fix double free in xlog_recover_commit_trans
authorDave Chinner <dchinner@redhat.com>
Sun, 28 Sep 2014 23:45:32 +0000 (09:45 +1000)
committerDave Chinner <david@fromorbit.com>
Sun, 28 Sep 2014 23:45:32 +0000 (09:45 +1000)
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>
fs/xfs/xfs_log_recover.c

index 6d1c78378c31affc49a2af53692cd52affcbd64c..89574ff2566ec58c0192d23c677a6b7e998bdf58 100644 (file)
@@ -3528,8 +3528,6 @@ out:
        if (!list_empty(&done_list))
                list_splice_init(&done_list, &trans->r_itemq);
 
-       xlog_recover_free_trans(trans);
-
        error2 = xfs_buf_delwri_submit(&buffer_list);
        return error ? error : error2;
 }
@@ -3554,6 +3552,10 @@ xlog_recovery_process_trans(
        if (flags & XLOG_WAS_CONT_TRANS)
                flags &= ~XLOG_CONTINUE_TRANS;
 
+       /*
+        * Callees must not free the trans structure. We'll decide if we need to
+        * free it or not based on the operation being done and it's result.
+        */
        switch (flags) {
        /* expected flag values */
        case 0:
@@ -3565,6 +3567,8 @@ xlog_recovery_process_trans(
                break;
        case XLOG_COMMIT_TRANS:
                error = xlog_recover_commit_trans(log, trans, pass);
+               /* success or fail, we are now done with this transaction. */
+               freeit = true;
                break;
 
        /* unexpected flag values */