aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r--fs/xfs/xfs_log_recover.c105
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)
56STATIC void xlog_recover_check_summary(xlog_t *); 56STATIC void xlog_recover_check_summary(xlog_t *);
57STATIC 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)
3037STATIC void
3038xlog_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); 3097out:
3098 xfs_trans_ail_cursor_done(ailp, &cur);
3099 spin_unlock(&ailp->xa_lock);
3117 return error; 3100 return error;
3118} 3101}
3119 3102