diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-10 02:23:07 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-10-10 02:23:07 -0400 |
commit | 6f97077ff6ef28e0f3b361b6ba9c95a222ef384b (patch) | |
tree | c541a0d113af184d0d45e3eddb3f89d434fdad58 | |
parent | 1987fd743415564e8c67f2f7ec0ae3c18a6b11cd (diff) |
xfs: rework refcount cow recovery error handling
The error handling in xfs_refcount_recover_cow_leftovers is confused
and can potentially leak memory, so rework it to release resources
correctly on error.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reported-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/libxfs/xfs_refcount.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 56bfef116423..b177ef33cd4c 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c | |||
@@ -1643,7 +1643,7 @@ xfs_refcount_recover_cow_leftovers( | |||
1643 | error = xfs_btree_query_range(cur, &low, &high, | 1643 | error = xfs_btree_query_range(cur, &low, &high, |
1644 | xfs_refcount_recover_extent, &debris); | 1644 | xfs_refcount_recover_extent, &debris); |
1645 | if (error) | 1645 | if (error) |
1646 | goto out_error; | 1646 | goto out_cursor; |
1647 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | 1647 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
1648 | xfs_buf_relse(agbp); | 1648 | xfs_buf_relse(agbp); |
1649 | 1649 | ||
@@ -1675,14 +1675,8 @@ xfs_refcount_recover_cow_leftovers( | |||
1675 | 1675 | ||
1676 | error = xfs_trans_commit(tp); | 1676 | error = xfs_trans_commit(tp); |
1677 | if (error) | 1677 | if (error) |
1678 | goto out_cancel; | 1678 | goto out_free; |
1679 | } | 1679 | } |
1680 | goto out_free; | ||
1681 | |||
1682 | out_defer: | ||
1683 | xfs_defer_cancel(&dfops); | ||
1684 | out_cancel: | ||
1685 | xfs_trans_cancel(tp); | ||
1686 | 1680 | ||
1687 | out_free: | 1681 | out_free: |
1688 | /* Free the leftover list */ | 1682 | /* Free the leftover list */ |
@@ -1690,11 +1684,15 @@ out_free: | |||
1690 | list_del(&rr->rr_list); | 1684 | list_del(&rr->rr_list); |
1691 | kmem_free(rr); | 1685 | kmem_free(rr); |
1692 | } | 1686 | } |
1693 | |||
1694 | return error; | 1687 | return error; |
1695 | 1688 | ||
1696 | out_error: | 1689 | out_cursor: |
1697 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 1690 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
1698 | xfs_buf_relse(agbp); | 1691 | xfs_buf_relse(agbp); |
1699 | return error; | 1692 | goto out_free; |
1693 | |||
1694 | out_defer: | ||
1695 | xfs_defer_cancel(&dfops); | ||
1696 | xfs_trans_cancel(tp); | ||
1697 | goto out_free; | ||
1700 | } | 1698 | } |