diff options
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 105 |
1 files changed, 44 insertions, 61 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 82d46ce69d5f..b411d4947318 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -54,10 +54,8 @@ STATIC void xlog_recover_insert_item_backq(xlog_recover_item_t **q, | |||
54 | xlog_recover_item_t *item); | 54 | xlog_recover_item_t *item); |
55 | #if defined(DEBUG) | 55 | #if defined(DEBUG) |
56 | STATIC void xlog_recover_check_summary(xlog_t *); | 56 | STATIC void xlog_recover_check_summary(xlog_t *); |
57 | STATIC void xlog_recover_check_ail(xfs_mount_t *, xfs_log_item_t *, int); | ||
58 | #else | 57 | #else |
59 | #define xlog_recover_check_summary(log) | 58 | #define xlog_recover_check_summary(log) |
60 | #define xlog_recover_check_ail(mp, lip, gen) | ||
61 | #endif | 59 | #endif |
62 | 60 | ||
63 | 61 | ||
@@ -1419,7 +1417,13 @@ xlog_recover_add_to_trans( | |||
1419 | return 0; | 1417 | return 0; |
1420 | item = trans->r_itemq; | 1418 | item = trans->r_itemq; |
1421 | if (item == NULL) { | 1419 | if (item == NULL) { |
1422 | ASSERT(*(uint *)dp == XFS_TRANS_HEADER_MAGIC); | 1420 | /* we need to catch log corruptions here */ |
1421 | if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { | ||
1422 | xlog_warn("XFS: xlog_recover_add_to_trans: " | ||
1423 | "bad header magic number"); | ||
1424 | ASSERT(0); | ||
1425 | return XFS_ERROR(EIO); | ||
1426 | } | ||
1423 | if (len == sizeof(xfs_trans_header_t)) | 1427 | if (len == sizeof(xfs_trans_header_t)) |
1424 | xlog_recover_add_item(&trans->r_itemq); | 1428 | xlog_recover_add_item(&trans->r_itemq); |
1425 | memcpy(&trans->r_theader, dp, len); /* d, s, l */ | 1429 | memcpy(&trans->r_theader, dp, len); /* d, s, l */ |
@@ -2452,8 +2456,8 @@ xlog_recover_do_inode_trans( | |||
2452 | break; | 2456 | break; |
2453 | 2457 | ||
2454 | case XFS_ILOG_DBROOT: | 2458 | case XFS_ILOG_DBROOT: |
2455 | xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len, | 2459 | xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len, |
2456 | &(dip->di_u.di_bmbt), | 2460 | &dip->di_u.di_bmbt, |
2457 | XFS_DFORK_DSIZE(dip, mp)); | 2461 | XFS_DFORK_DSIZE(dip, mp)); |
2458 | break; | 2462 | break; |
2459 | 2463 | ||
@@ -2490,8 +2494,8 @@ xlog_recover_do_inode_trans( | |||
2490 | 2494 | ||
2491 | case XFS_ILOG_ABROOT: | 2495 | case XFS_ILOG_ABROOT: |
2492 | dest = XFS_DFORK_APTR(dip); | 2496 | dest = XFS_DFORK_APTR(dip); |
2493 | xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len, | 2497 | xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, |
2494 | (xfs_bmdr_block_t*)dest, | 2498 | len, (xfs_bmdr_block_t*)dest, |
2495 | XFS_DFORK_ASIZE(dip, mp)); | 2499 | XFS_DFORK_ASIZE(dip, mp)); |
2496 | break; | 2500 | break; |
2497 | 2501 | ||
@@ -2683,11 +2687,11 @@ xlog_recover_do_efi_trans( | |||
2683 | efip->efi_next_extent = efi_formatp->efi_nextents; | 2687 | efip->efi_next_extent = efi_formatp->efi_nextents; |
2684 | efip->efi_flags |= XFS_EFI_COMMITTED; | 2688 | efip->efi_flags |= XFS_EFI_COMMITTED; |
2685 | 2689 | ||
2686 | spin_lock(&mp->m_ail_lock); | 2690 | spin_lock(&log->l_ailp->xa_lock); |
2687 | /* | 2691 | /* |
2688 | * xfs_trans_update_ail() drops the AIL lock. | 2692 | * xfs_trans_ail_update() drops the AIL lock. |
2689 | */ | 2693 | */ |
2690 | xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn); | 2694 | xfs_trans_ail_update(log->l_ailp, (xfs_log_item_t *)efip, lsn); |
2691 | return 0; | 2695 | return 0; |
2692 | } | 2696 | } |
2693 | 2697 | ||
@@ -2706,12 +2710,12 @@ xlog_recover_do_efd_trans( | |||
2706 | xlog_recover_item_t *item, | 2710 | xlog_recover_item_t *item, |
2707 | int pass) | 2711 | int pass) |
2708 | { | 2712 | { |
2709 | xfs_mount_t *mp; | ||
2710 | xfs_efd_log_format_t *efd_formatp; | 2713 | xfs_efd_log_format_t *efd_formatp; |
2711 | xfs_efi_log_item_t *efip = NULL; | 2714 | xfs_efi_log_item_t *efip = NULL; |
2712 | xfs_log_item_t *lip; | 2715 | xfs_log_item_t *lip; |
2713 | int gen; | ||
2714 | __uint64_t efi_id; | 2716 | __uint64_t efi_id; |
2717 | struct xfs_ail_cursor cur; | ||
2718 | struct xfs_ail *ailp = log->l_ailp; | ||
2715 | 2719 | ||
2716 | if (pass == XLOG_RECOVER_PASS1) { | 2720 | if (pass == XLOG_RECOVER_PASS1) { |
2717 | return; | 2721 | return; |
@@ -2728,25 +2732,26 @@ xlog_recover_do_efd_trans( | |||
2728 | * Search for the efi with the id in the efd format structure | 2732 | * Search for the efi with the id in the efd format structure |
2729 | * in the AIL. | 2733 | * in the AIL. |
2730 | */ | 2734 | */ |
2731 | mp = log->l_mp; | 2735 | spin_lock(&ailp->xa_lock); |
2732 | spin_lock(&mp->m_ail_lock); | 2736 | lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); |
2733 | lip = xfs_trans_first_ail(mp, &gen); | ||
2734 | while (lip != NULL) { | 2737 | while (lip != NULL) { |
2735 | if (lip->li_type == XFS_LI_EFI) { | 2738 | if (lip->li_type == XFS_LI_EFI) { |
2736 | efip = (xfs_efi_log_item_t *)lip; | 2739 | efip = (xfs_efi_log_item_t *)lip; |
2737 | if (efip->efi_format.efi_id == efi_id) { | 2740 | if (efip->efi_format.efi_id == efi_id) { |
2738 | /* | 2741 | /* |
2739 | * xfs_trans_delete_ail() drops the | 2742 | * xfs_trans_ail_delete() drops the |
2740 | * AIL lock. | 2743 | * AIL lock. |
2741 | */ | 2744 | */ |
2742 | xfs_trans_delete_ail(mp, lip); | 2745 | xfs_trans_ail_delete(ailp, lip); |
2743 | xfs_efi_item_free(efip); | 2746 | xfs_efi_item_free(efip); |
2744 | return; | 2747 | spin_lock(&ailp->xa_lock); |
2748 | break; | ||
2745 | } | 2749 | } |
2746 | } | 2750 | } |
2747 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | 2751 | lip = xfs_trans_ail_cursor_next(ailp, &cur); |
2748 | } | 2752 | } |
2749 | spin_unlock(&mp->m_ail_lock); | 2753 | xfs_trans_ail_cursor_done(ailp, &cur); |
2754 | spin_unlock(&ailp->xa_lock); | ||
2750 | } | 2755 | } |
2751 | 2756 | ||
2752 | /* | 2757 | /* |
@@ -3030,33 +3035,6 @@ abort_error: | |||
3030 | } | 3035 | } |
3031 | 3036 | ||
3032 | /* | 3037 | /* |
3033 | * Verify that once we've encountered something other than an EFI | ||
3034 | * in the AIL that there are no more EFIs in the AIL. | ||
3035 | */ | ||
3036 | #if defined(DEBUG) | ||
3037 | STATIC void | ||
3038 | xlog_recover_check_ail( | ||
3039 | xfs_mount_t *mp, | ||
3040 | xfs_log_item_t *lip, | ||
3041 | int gen) | ||
3042 | { | ||
3043 | int orig_gen = gen; | ||
3044 | |||
3045 | do { | ||
3046 | ASSERT(lip->li_type != XFS_LI_EFI); | ||
3047 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | ||
3048 | /* | ||
3049 | * The check will be bogus if we restart from the | ||
3050 | * beginning of the AIL, so ASSERT that we don't. | ||
3051 | * We never should since we're holding the AIL lock | ||
3052 | * the entire time. | ||
3053 | */ | ||
3054 | ASSERT(gen == orig_gen); | ||
3055 | } while (lip != NULL); | ||
3056 | } | ||
3057 | #endif /* DEBUG */ | ||
3058 | |||
3059 | /* | ||
3060 | * When this is called, all of the EFIs which did not have | 3038 | * When this is called, all of the EFIs which did not have |
3061 | * corresponding EFDs should be in the AIL. What we do now | 3039 | * corresponding EFDs should be in the AIL. What we do now |
3062 | * is free the extents associated with each one. | 3040 | * is free the extents associated with each one. |
@@ -3080,20 +3058,23 @@ xlog_recover_process_efis( | |||
3080 | { | 3058 | { |
3081 | xfs_log_item_t *lip; | 3059 | xfs_log_item_t *lip; |
3082 | xfs_efi_log_item_t *efip; | 3060 | xfs_efi_log_item_t *efip; |
3083 | int gen; | ||
3084 | xfs_mount_t *mp; | ||
3085 | int error = 0; | 3061 | int error = 0; |
3062 | struct xfs_ail_cursor cur; | ||
3063 | struct xfs_ail *ailp; | ||
3086 | 3064 | ||
3087 | mp = log->l_mp; | 3065 | ailp = log->l_ailp; |
3088 | spin_lock(&mp->m_ail_lock); | 3066 | spin_lock(&ailp->xa_lock); |
3089 | 3067 | lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); | |
3090 | lip = xfs_trans_first_ail(mp, &gen); | ||
3091 | while (lip != NULL) { | 3068 | while (lip != NULL) { |
3092 | /* | 3069 | /* |
3093 | * We're done when we see something other than an EFI. | 3070 | * We're done when we see something other than an EFI. |
3071 | * There should be no EFIs left in the AIL now. | ||
3094 | */ | 3072 | */ |
3095 | if (lip->li_type != XFS_LI_EFI) { | 3073 | if (lip->li_type != XFS_LI_EFI) { |
3096 | xlog_recover_check_ail(mp, lip, gen); | 3074 | #ifdef DEBUG |
3075 | for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur)) | ||
3076 | ASSERT(lip->li_type != XFS_LI_EFI); | ||
3077 | #endif | ||
3097 | break; | 3078 | break; |
3098 | } | 3079 | } |
3099 | 3080 | ||
@@ -3102,18 +3083,20 @@ xlog_recover_process_efis( | |||
3102 | */ | 3083 | */ |
3103 | efip = (xfs_efi_log_item_t *)lip; | 3084 | efip = (xfs_efi_log_item_t *)lip; |
3104 | if (efip->efi_flags & XFS_EFI_RECOVERED) { | 3085 | if (efip->efi_flags & XFS_EFI_RECOVERED) { |
3105 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | 3086 | lip = xfs_trans_ail_cursor_next(ailp, &cur); |
3106 | continue; | 3087 | continue; |
3107 | } | 3088 | } |
3108 | 3089 | ||
3109 | spin_unlock(&mp->m_ail_lock); | 3090 | spin_unlock(&ailp->xa_lock); |
3110 | error = xlog_recover_process_efi(mp, efip); | 3091 | error = xlog_recover_process_efi(log->l_mp, efip); |
3092 | spin_lock(&ailp->xa_lock); | ||
3111 | if (error) | 3093 | if (error) |
3112 | return error; | 3094 | goto out; |
3113 | spin_lock(&mp->m_ail_lock); | 3095 | lip = xfs_trans_ail_cursor_next(ailp, &cur); |
3114 | lip = xfs_trans_next_ail(mp, lip, &gen, NULL); | ||
3115 | } | 3096 | } |
3116 | spin_unlock(&mp->m_ail_lock); | 3097 | out: |
3098 | xfs_trans_ail_cursor_done(ailp, &cur); | ||
3099 | spin_unlock(&ailp->xa_lock); | ||
3117 | return error; | 3100 | return error; |
3118 | } | 3101 | } |
3119 | 3102 | ||