Commit 2a84108f authored by Mark Tinguely's avatar Mark Tinguely Committed by Ben Myers

xfs: free the list of recovery items on error

Recovery builds a list of items on the transaction's
r_itemq head. Normally these items are committed and freed.
But in the event of a recovery error, these allocations
are leaked.

If the error occurs during item reordering, then reconstruct
the r_itemq list before deleting the list to avoid leaking
the entries that were on one of the temporary lists.
Signed-off-by: default avatarMark Tinguely <tinguely@sgi.com>
Reviewed-by: default avatarBen Myers <bpm@sgi.com>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent dff6efc3
...@@ -1651,6 +1651,7 @@ xlog_recover_reorder_trans( ...@@ -1651,6 +1651,7 @@ xlog_recover_reorder_trans(
int pass) int pass)
{ {
xlog_recover_item_t *item, *n; xlog_recover_item_t *item, *n;
int error = 0;
LIST_HEAD(sort_list); LIST_HEAD(sort_list);
LIST_HEAD(cancel_list); LIST_HEAD(cancel_list);
LIST_HEAD(buffer_list); LIST_HEAD(buffer_list);
...@@ -1692,9 +1693,17 @@ xlog_recover_reorder_trans( ...@@ -1692,9 +1693,17 @@ xlog_recover_reorder_trans(
"%s: unrecognized type of log operation", "%s: unrecognized type of log operation",
__func__); __func__);
ASSERT(0); ASSERT(0);
return XFS_ERROR(EIO); /*
* return the remaining items back to the transaction
* item list so they can be freed in caller.
*/
if (!list_empty(&sort_list))
list_splice_init(&sort_list, &trans->r_itemq);
error = XFS_ERROR(EIO);
goto out;
} }
} }
out:
ASSERT(list_empty(&sort_list)); ASSERT(list_empty(&sort_list));
if (!list_empty(&buffer_list)) if (!list_empty(&buffer_list))
list_splice(&buffer_list, &trans->r_itemq); list_splice(&buffer_list, &trans->r_itemq);
...@@ -1704,7 +1713,7 @@ xlog_recover_reorder_trans( ...@@ -1704,7 +1713,7 @@ xlog_recover_reorder_trans(
list_splice_tail(&inode_buffer_list, &trans->r_itemq); list_splice_tail(&inode_buffer_list, &trans->r_itemq);
if (!list_empty(&cancel_list)) if (!list_empty(&cancel_list))
list_splice_tail(&cancel_list, &trans->r_itemq); list_splice_tail(&cancel_list, &trans->r_itemq);
return 0; return error;
} }
/* /*
...@@ -3608,8 +3617,10 @@ xlog_recover_process_data( ...@@ -3608,8 +3617,10 @@ xlog_recover_process_data(
error = XFS_ERROR(EIO); error = XFS_ERROR(EIO);
break; break;
} }
if (error) if (error) {
xlog_recover_free_trans(trans);
return error; return error;
}
} }
dp += be32_to_cpu(ohead->oh_len); dp += be32_to_cpu(ohead->oh_len);
num_logops--; num_logops--;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment