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: Mark Tinguely <tinguely@sgi.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
Родитель
dff6efc326
Коммит
2a84108fe2
|
@ -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(
|
||||||
"%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(
|
||||||
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(
|
||||||
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--;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче