diff options
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index eae16920655b..bce53ac81096 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -1654,6 +1654,7 @@ xlog_recover_reorder_trans( | |||
1654 | int pass) | 1654 | int pass) |
1655 | { | 1655 | { |
1656 | xlog_recover_item_t *item, *n; | 1656 | xlog_recover_item_t *item, *n; |
1657 | int error = 0; | ||
1657 | LIST_HEAD(sort_list); | 1658 | LIST_HEAD(sort_list); |
1658 | LIST_HEAD(cancel_list); | 1659 | LIST_HEAD(cancel_list); |
1659 | LIST_HEAD(buffer_list); | 1660 | LIST_HEAD(buffer_list); |
@@ -1695,9 +1696,17 @@ xlog_recover_reorder_trans( | |||
1695 | "%s: unrecognized type of log operation", | 1696 | "%s: unrecognized type of log operation", |
1696 | __func__); | 1697 | __func__); |
1697 | ASSERT(0); | 1698 | ASSERT(0); |
1698 | return XFS_ERROR(EIO); | 1699 | /* |
1700 | * return the remaining items back to the transaction | ||
1701 | * item list so they can be freed in caller. | ||
1702 | */ | ||
1703 | if (!list_empty(&sort_list)) | ||
1704 | list_splice_init(&sort_list, &trans->r_itemq); | ||
1705 | error = XFS_ERROR(EIO); | ||
1706 | goto out; | ||
1699 | } | 1707 | } |
1700 | } | 1708 | } |
1709 | out: | ||
1701 | ASSERT(list_empty(&sort_list)); | 1710 | ASSERT(list_empty(&sort_list)); |
1702 | if (!list_empty(&buffer_list)) | 1711 | if (!list_empty(&buffer_list)) |
1703 | list_splice(&buffer_list, &trans->r_itemq); | 1712 | list_splice(&buffer_list, &trans->r_itemq); |
@@ -1707,7 +1716,7 @@ xlog_recover_reorder_trans( | |||
1707 | list_splice_tail(&inode_buffer_list, &trans->r_itemq); | 1716 | list_splice_tail(&inode_buffer_list, &trans->r_itemq); |
1708 | if (!list_empty(&cancel_list)) | 1717 | if (!list_empty(&cancel_list)) |
1709 | list_splice_tail(&cancel_list, &trans->r_itemq); | 1718 | list_splice_tail(&cancel_list, &trans->r_itemq); |
1710 | return 0; | 1719 | return error; |
1711 | } | 1720 | } |
1712 | 1721 | ||
1713 | /* | 1722 | /* |
@@ -2517,19 +2526,19 @@ xlog_recover_buffer_pass2( | |||
2517 | * | 2526 | * |
2518 | * Also make sure that only inode buffers with good sizes stay in | 2527 | * Also make sure that only inode buffers with good sizes stay in |
2519 | * the buffer cache. The kernel moves inodes in buffers of 1 block | 2528 | * the buffer cache. The kernel moves inodes in buffers of 1 block |
2520 | * or XFS_INODE_CLUSTER_SIZE bytes, whichever is bigger. The inode | 2529 | * or mp->m_inode_cluster_size bytes, whichever is bigger. The inode |
2521 | * buffers in the log can be a different size if the log was generated | 2530 | * buffers in the log can be a different size if the log was generated |
2522 | * by an older kernel using unclustered inode buffers or a newer kernel | 2531 | * by an older kernel using unclustered inode buffers or a newer kernel |
2523 | * running with a different inode cluster size. Regardless, if the | 2532 | * running with a different inode cluster size. Regardless, if the |
2524 | * the inode buffer size isn't MAX(blocksize, XFS_INODE_CLUSTER_SIZE) | 2533 | * the inode buffer size isn't MAX(blocksize, mp->m_inode_cluster_size) |
2525 | * for *our* value of XFS_INODE_CLUSTER_SIZE, then we need to keep | 2534 | * for *our* value of mp->m_inode_cluster_size, then we need to keep |
2526 | * the buffer out of the buffer cache so that the buffer won't | 2535 | * the buffer out of the buffer cache so that the buffer won't |
2527 | * overlap with future reads of those inodes. | 2536 | * overlap with future reads of those inodes. |
2528 | */ | 2537 | */ |
2529 | if (XFS_DINODE_MAGIC == | 2538 | if (XFS_DINODE_MAGIC == |
2530 | be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) && | 2539 | be16_to_cpu(*((__be16 *)xfs_buf_offset(bp, 0))) && |
2531 | (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize, | 2540 | (BBTOB(bp->b_io_length) != MAX(log->l_mp->m_sb.sb_blocksize, |
2532 | (__uint32_t)XFS_INODE_CLUSTER_SIZE(log->l_mp)))) { | 2541 | (__uint32_t)log->l_mp->m_inode_cluster_size))) { |
2533 | xfs_buf_stale(bp); | 2542 | xfs_buf_stale(bp); |
2534 | error = xfs_bwrite(bp); | 2543 | error = xfs_bwrite(bp); |
2535 | } else { | 2544 | } else { |
@@ -3202,10 +3211,10 @@ xlog_recover_do_icreate_pass2( | |||
3202 | } | 3211 | } |
3203 | 3212 | ||
3204 | /* existing allocation is fixed value */ | 3213 | /* existing allocation is fixed value */ |
3205 | ASSERT(count == XFS_IALLOC_INODES(mp)); | 3214 | ASSERT(count == mp->m_ialloc_inos); |
3206 | ASSERT(length == XFS_IALLOC_BLOCKS(mp)); | 3215 | ASSERT(length == mp->m_ialloc_blks); |
3207 | if (count != XFS_IALLOC_INODES(mp) || | 3216 | if (count != mp->m_ialloc_inos || |
3208 | length != XFS_IALLOC_BLOCKS(mp)) { | 3217 | length != mp->m_ialloc_blks) { |
3209 | xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2"); | 3218 | xfs_warn(log->l_mp, "xlog_recover_do_icreate_trans: bad count 2"); |
3210 | return EINVAL; | 3219 | return EINVAL; |
3211 | } | 3220 | } |
@@ -3611,8 +3620,10 @@ xlog_recover_process_data( | |||
3611 | error = XFS_ERROR(EIO); | 3620 | error = XFS_ERROR(EIO); |
3612 | break; | 3621 | break; |
3613 | } | 3622 | } |
3614 | if (error) | 3623 | if (error) { |
3624 | xlog_recover_free_trans(trans); | ||
3615 | return error; | 3625 | return error; |
3626 | } | ||
3616 | } | 3627 | } |
3617 | dp += be32_to_cpu(ohead->oh_len); | 3628 | dp += be32_to_cpu(ohead->oh_len); |
3618 | num_logops--; | 3629 | num_logops--; |