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.c416
1 files changed, 165 insertions, 251 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 70e3ba32e6be..35cca98bd94c 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -36,7 +36,6 @@
36#include "xfs_dinode.h" 36#include "xfs_dinode.h"
37#include "xfs_inode.h" 37#include "xfs_inode.h"
38#include "xfs_inode_item.h" 38#include "xfs_inode_item.h"
39#include "xfs_imap.h"
40#include "xfs_alloc.h" 39#include "xfs_alloc.h"
41#include "xfs_ialloc.h" 40#include "xfs_ialloc.h"
42#include "xfs_log_priv.h" 41#include "xfs_log_priv.h"
@@ -54,10 +53,8 @@ STATIC void xlog_recover_insert_item_backq(xlog_recover_item_t **q,
54 xlog_recover_item_t *item); 53 xlog_recover_item_t *item);
55#if defined(DEBUG) 54#if defined(DEBUG)
56STATIC void xlog_recover_check_summary(xlog_t *); 55STATIC void xlog_recover_check_summary(xlog_t *);
57STATIC void xlog_recover_check_ail(xfs_mount_t *, xfs_log_item_t *, int);
58#else 56#else
59#define xlog_recover_check_summary(log) 57#define xlog_recover_check_summary(log)
60#define xlog_recover_check_ail(mp, lip, gen)
61#endif 58#endif
62 59
63 60
@@ -270,21 +267,16 @@ STATIC void
270xlog_recover_iodone( 267xlog_recover_iodone(
271 struct xfs_buf *bp) 268 struct xfs_buf *bp)
272{ 269{
273 xfs_mount_t *mp;
274
275 ASSERT(XFS_BUF_FSPRIVATE(bp, void *));
276
277 if (XFS_BUF_GETERROR(bp)) { 270 if (XFS_BUF_GETERROR(bp)) {
278 /* 271 /*
279 * We're not going to bother about retrying 272 * We're not going to bother about retrying
280 * this during recovery. One strike! 273 * this during recovery. One strike!
281 */ 274 */
282 mp = XFS_BUF_FSPRIVATE(bp, xfs_mount_t *);
283 xfs_ioerror_alert("xlog_recover_iodone", 275 xfs_ioerror_alert("xlog_recover_iodone",
284 mp, bp, XFS_BUF_ADDR(bp)); 276 bp->b_mount, bp, XFS_BUF_ADDR(bp));
285 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); 277 xfs_force_shutdown(bp->b_mount, SHUTDOWN_META_IO_ERROR);
286 } 278 }
287 XFS_BUF_SET_FSPRIVATE(bp, NULL); 279 bp->b_mount = NULL;
288 XFS_BUF_CLR_IODONE_FUNC(bp); 280 XFS_BUF_CLR_IODONE_FUNC(bp);
289 xfs_biodone(bp); 281 xfs_biodone(bp);
290} 282}
@@ -2228,9 +2220,8 @@ xlog_recover_do_buffer_trans(
2228 XFS_BUF_STALE(bp); 2220 XFS_BUF_STALE(bp);
2229 error = xfs_bwrite(mp, bp); 2221 error = xfs_bwrite(mp, bp);
2230 } else { 2222 } else {
2231 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2223 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2232 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2224 bp->b_mount = mp;
2233 XFS_BUF_SET_FSPRIVATE(bp, mp);
2234 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2225 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2235 xfs_bdwrite(mp, bp); 2226 xfs_bdwrite(mp, bp);
2236 } 2227 }
@@ -2247,7 +2238,6 @@ xlog_recover_do_inode_trans(
2247 xfs_inode_log_format_t *in_f; 2238 xfs_inode_log_format_t *in_f;
2248 xfs_mount_t *mp; 2239 xfs_mount_t *mp;
2249 xfs_buf_t *bp; 2240 xfs_buf_t *bp;
2250 xfs_imap_t imap;
2251 xfs_dinode_t *dip; 2241 xfs_dinode_t *dip;
2252 xfs_ino_t ino; 2242 xfs_ino_t ino;
2253 int len; 2243 int len;
@@ -2275,54 +2265,35 @@ xlog_recover_do_inode_trans(
2275 } 2265 }
2276 ino = in_f->ilf_ino; 2266 ino = in_f->ilf_ino;
2277 mp = log->l_mp; 2267 mp = log->l_mp;
2278 if (ITEM_TYPE(item) == XFS_LI_INODE) {
2279 imap.im_blkno = (xfs_daddr_t)in_f->ilf_blkno;
2280 imap.im_len = in_f->ilf_len;
2281 imap.im_boffset = in_f->ilf_boffset;
2282 } else {
2283 /*
2284 * It's an old inode format record. We don't know where
2285 * its cluster is located on disk, and we can't allow
2286 * xfs_imap() to figure it out because the inode btrees
2287 * are not ready to be used. Therefore do not pass the
2288 * XFS_IMAP_LOOKUP flag to xfs_imap(). This will give
2289 * us only the single block in which the inode lives
2290 * rather than its cluster, so we must make sure to
2291 * invalidate the buffer when we write it out below.
2292 */
2293 imap.im_blkno = 0;
2294 error = xfs_imap(log->l_mp, NULL, ino, &imap, 0);
2295 if (error)
2296 goto error;
2297 }
2298 2268
2299 /* 2269 /*
2300 * Inode buffers can be freed, look out for it, 2270 * Inode buffers can be freed, look out for it,
2301 * and do not replay the inode. 2271 * and do not replay the inode.
2302 */ 2272 */
2303 if (xlog_check_buffer_cancelled(log, imap.im_blkno, imap.im_len, 0)) { 2273 if (xlog_check_buffer_cancelled(log, in_f->ilf_blkno,
2274 in_f->ilf_len, 0)) {
2304 error = 0; 2275 error = 0;
2305 goto error; 2276 goto error;
2306 } 2277 }
2307 2278
2308 bp = xfs_buf_read_flags(mp->m_ddev_targp, imap.im_blkno, imap.im_len, 2279 bp = xfs_buf_read_flags(mp->m_ddev_targp, in_f->ilf_blkno,
2309 XFS_BUF_LOCK); 2280 in_f->ilf_len, XFS_BUF_LOCK);
2310 if (XFS_BUF_ISERROR(bp)) { 2281 if (XFS_BUF_ISERROR(bp)) {
2311 xfs_ioerror_alert("xlog_recover_do..(read#2)", mp, 2282 xfs_ioerror_alert("xlog_recover_do..(read#2)", mp,
2312 bp, imap.im_blkno); 2283 bp, in_f->ilf_blkno);
2313 error = XFS_BUF_GETERROR(bp); 2284 error = XFS_BUF_GETERROR(bp);
2314 xfs_buf_relse(bp); 2285 xfs_buf_relse(bp);
2315 goto error; 2286 goto error;
2316 } 2287 }
2317 error = 0; 2288 error = 0;
2318 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); 2289 ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
2319 dip = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); 2290 dip = (xfs_dinode_t *)xfs_buf_offset(bp, in_f->ilf_boffset);
2320 2291
2321 /* 2292 /*
2322 * Make sure the place we're flushing out to really looks 2293 * Make sure the place we're flushing out to really looks
2323 * like an inode! 2294 * like an inode!
2324 */ 2295 */
2325 if (unlikely(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC)) { 2296 if (unlikely(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC)) {
2326 xfs_buf_relse(bp); 2297 xfs_buf_relse(bp);
2327 xfs_fs_cmn_err(CE_ALERT, mp, 2298 xfs_fs_cmn_err(CE_ALERT, mp,
2328 "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld", 2299 "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
@@ -2345,12 +2316,12 @@ xlog_recover_do_inode_trans(
2345 } 2316 }
2346 2317
2347 /* Skip replay when the on disk inode is newer than the log one */ 2318 /* Skip replay when the on disk inode is newer than the log one */
2348 if (dicp->di_flushiter < be16_to_cpu(dip->di_core.di_flushiter)) { 2319 if (dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
2349 /* 2320 /*
2350 * Deal with the wrap case, DI_MAX_FLUSH is less 2321 * Deal with the wrap case, DI_MAX_FLUSH is less
2351 * than smaller numbers 2322 * than smaller numbers
2352 */ 2323 */
2353 if (be16_to_cpu(dip->di_core.di_flushiter) == DI_MAX_FLUSH && 2324 if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
2354 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) { 2325 dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
2355 /* do nothing */ 2326 /* do nothing */
2356 } else { 2327 } else {
@@ -2410,7 +2381,7 @@ xlog_recover_do_inode_trans(
2410 error = EFSCORRUPTED; 2381 error = EFSCORRUPTED;
2411 goto error; 2382 goto error;
2412 } 2383 }
2413 if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) { 2384 if (unlikely(item->ri_buf[1].i_len > sizeof(struct xfs_icdinode))) {
2414 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", 2385 XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
2415 XFS_ERRLEVEL_LOW, mp, dicp); 2386 XFS_ERRLEVEL_LOW, mp, dicp);
2416 xfs_buf_relse(bp); 2387 xfs_buf_relse(bp);
@@ -2422,23 +2393,24 @@ xlog_recover_do_inode_trans(
2422 } 2393 }
2423 2394
2424 /* The core is in in-core format */ 2395 /* The core is in in-core format */
2425 xfs_dinode_to_disk(&dip->di_core, 2396 xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr);
2426 (xfs_icdinode_t *)item->ri_buf[1].i_addr);
2427 2397
2428 /* the rest is in on-disk format */ 2398 /* the rest is in on-disk format */
2429 if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) { 2399 if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) {
2430 memcpy((xfs_caddr_t) dip + sizeof(xfs_dinode_core_t), 2400 memcpy((xfs_caddr_t) dip + sizeof(struct xfs_icdinode),
2431 item->ri_buf[1].i_addr + sizeof(xfs_dinode_core_t), 2401 item->ri_buf[1].i_addr + sizeof(struct xfs_icdinode),
2432 item->ri_buf[1].i_len - sizeof(xfs_dinode_core_t)); 2402 item->ri_buf[1].i_len - sizeof(struct xfs_icdinode));
2433 } 2403 }
2434 2404
2435 fields = in_f->ilf_fields; 2405 fields = in_f->ilf_fields;
2436 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) { 2406 switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
2437 case XFS_ILOG_DEV: 2407 case XFS_ILOG_DEV:
2438 dip->di_u.di_dev = cpu_to_be32(in_f->ilf_u.ilfu_rdev); 2408 xfs_dinode_put_rdev(dip, in_f->ilf_u.ilfu_rdev);
2439 break; 2409 break;
2440 case XFS_ILOG_UUID: 2410 case XFS_ILOG_UUID:
2441 dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid; 2411 memcpy(XFS_DFORK_DPTR(dip),
2412 &in_f->ilf_u.ilfu_uuid,
2413 sizeof(uuid_t));
2442 break; 2414 break;
2443 } 2415 }
2444 2416
@@ -2454,12 +2426,12 @@ xlog_recover_do_inode_trans(
2454 switch (fields & XFS_ILOG_DFORK) { 2426 switch (fields & XFS_ILOG_DFORK) {
2455 case XFS_ILOG_DDATA: 2427 case XFS_ILOG_DDATA:
2456 case XFS_ILOG_DEXT: 2428 case XFS_ILOG_DEXT:
2457 memcpy(&dip->di_u, src, len); 2429 memcpy(XFS_DFORK_DPTR(dip), src, len);
2458 break; 2430 break;
2459 2431
2460 case XFS_ILOG_DBROOT: 2432 case XFS_ILOG_DBROOT:
2461 xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len, 2433 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len,
2462 &(dip->di_u.di_bmbt), 2434 (xfs_bmdr_block_t *)XFS_DFORK_DPTR(dip),
2463 XFS_DFORK_DSIZE(dip, mp)); 2435 XFS_DFORK_DSIZE(dip, mp));
2464 break; 2436 break;
2465 2437
@@ -2496,8 +2468,8 @@ xlog_recover_do_inode_trans(
2496 2468
2497 case XFS_ILOG_ABROOT: 2469 case XFS_ILOG_ABROOT:
2498 dest = XFS_DFORK_APTR(dip); 2470 dest = XFS_DFORK_APTR(dip);
2499 xfs_bmbt_to_bmdr((xfs_bmbt_block_t *)src, len, 2471 xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src,
2500 (xfs_bmdr_block_t*)dest, 2472 len, (xfs_bmdr_block_t*)dest,
2501 XFS_DFORK_ASIZE(dip, mp)); 2473 XFS_DFORK_ASIZE(dip, mp));
2502 break; 2474 break;
2503 2475
@@ -2512,9 +2484,8 @@ xlog_recover_do_inode_trans(
2512 2484
2513write_inode_buffer: 2485write_inode_buffer:
2514 if (ITEM_TYPE(item) == XFS_LI_INODE) { 2486 if (ITEM_TYPE(item) == XFS_LI_INODE) {
2515 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2487 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2516 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2488 bp->b_mount = mp;
2517 XFS_BUF_SET_FSPRIVATE(bp, mp);
2518 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2489 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2519 xfs_bdwrite(mp, bp); 2490 xfs_bdwrite(mp, bp);
2520 } else { 2491 } else {
@@ -2645,9 +2616,8 @@ xlog_recover_do_dquot_trans(
2645 memcpy(ddq, recddq, item->ri_buf[1].i_len); 2616 memcpy(ddq, recddq, item->ri_buf[1].i_len);
2646 2617
2647 ASSERT(dq_f->qlf_size == 2); 2618 ASSERT(dq_f->qlf_size == 2);
2648 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) == NULL || 2619 ASSERT(bp->b_mount == NULL || bp->b_mount == mp);
2649 XFS_BUF_FSPRIVATE(bp, xfs_mount_t *) == mp); 2620 bp->b_mount = mp;
2650 XFS_BUF_SET_FSPRIVATE(bp, mp);
2651 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone); 2621 XFS_BUF_SET_IODONE_FUNC(bp, xlog_recover_iodone);
2652 xfs_bdwrite(mp, bp); 2622 xfs_bdwrite(mp, bp);
2653 2623
@@ -2689,11 +2659,11 @@ xlog_recover_do_efi_trans(
2689 efip->efi_next_extent = efi_formatp->efi_nextents; 2659 efip->efi_next_extent = efi_formatp->efi_nextents;
2690 efip->efi_flags |= XFS_EFI_COMMITTED; 2660 efip->efi_flags |= XFS_EFI_COMMITTED;
2691 2661
2692 spin_lock(&mp->m_ail_lock); 2662 spin_lock(&log->l_ailp->xa_lock);
2693 /* 2663 /*
2694 * xfs_trans_update_ail() drops the AIL lock. 2664 * xfs_trans_ail_update() drops the AIL lock.
2695 */ 2665 */
2696 xfs_trans_update_ail(mp, (xfs_log_item_t *)efip, lsn); 2666 xfs_trans_ail_update(log->l_ailp, (xfs_log_item_t *)efip, lsn);
2697 return 0; 2667 return 0;
2698} 2668}
2699 2669
@@ -2712,12 +2682,12 @@ xlog_recover_do_efd_trans(
2712 xlog_recover_item_t *item, 2682 xlog_recover_item_t *item,
2713 int pass) 2683 int pass)
2714{ 2684{
2715 xfs_mount_t *mp;
2716 xfs_efd_log_format_t *efd_formatp; 2685 xfs_efd_log_format_t *efd_formatp;
2717 xfs_efi_log_item_t *efip = NULL; 2686 xfs_efi_log_item_t *efip = NULL;
2718 xfs_log_item_t *lip; 2687 xfs_log_item_t *lip;
2719 int gen;
2720 __uint64_t efi_id; 2688 __uint64_t efi_id;
2689 struct xfs_ail_cursor cur;
2690 struct xfs_ail *ailp = log->l_ailp;
2721 2691
2722 if (pass == XLOG_RECOVER_PASS1) { 2692 if (pass == XLOG_RECOVER_PASS1) {
2723 return; 2693 return;
@@ -2734,25 +2704,26 @@ xlog_recover_do_efd_trans(
2734 * Search for the efi with the id in the efd format structure 2704 * Search for the efi with the id in the efd format structure
2735 * in the AIL. 2705 * in the AIL.
2736 */ 2706 */
2737 mp = log->l_mp; 2707 spin_lock(&ailp->xa_lock);
2738 spin_lock(&mp->m_ail_lock); 2708 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
2739 lip = xfs_trans_first_ail(mp, &gen);
2740 while (lip != NULL) { 2709 while (lip != NULL) {
2741 if (lip->li_type == XFS_LI_EFI) { 2710 if (lip->li_type == XFS_LI_EFI) {
2742 efip = (xfs_efi_log_item_t *)lip; 2711 efip = (xfs_efi_log_item_t *)lip;
2743 if (efip->efi_format.efi_id == efi_id) { 2712 if (efip->efi_format.efi_id == efi_id) {
2744 /* 2713 /*
2745 * xfs_trans_delete_ail() drops the 2714 * xfs_trans_ail_delete() drops the
2746 * AIL lock. 2715 * AIL lock.
2747 */ 2716 */
2748 xfs_trans_delete_ail(mp, lip); 2717 xfs_trans_ail_delete(ailp, lip);
2749 xfs_efi_item_free(efip); 2718 xfs_efi_item_free(efip);
2750 return; 2719 spin_lock(&ailp->xa_lock);
2720 break;
2751 } 2721 }
2752 } 2722 }
2753 lip = xfs_trans_next_ail(mp, lip, &gen, NULL); 2723 lip = xfs_trans_ail_cursor_next(ailp, &cur);
2754 } 2724 }
2755 spin_unlock(&mp->m_ail_lock); 2725 xfs_trans_ail_cursor_done(ailp, &cur);
2726 spin_unlock(&ailp->xa_lock);
2756} 2727}
2757 2728
2758/* 2729/*
@@ -3036,33 +3007,6 @@ abort_error:
3036} 3007}
3037 3008
3038/* 3009/*
3039 * Verify that once we've encountered something other than an EFI
3040 * in the AIL that there are no more EFIs in the AIL.
3041 */
3042#if defined(DEBUG)
3043STATIC void
3044xlog_recover_check_ail(
3045 xfs_mount_t *mp,
3046 xfs_log_item_t *lip,
3047 int gen)
3048{
3049 int orig_gen = gen;
3050
3051 do {
3052 ASSERT(lip->li_type != XFS_LI_EFI);
3053 lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
3054 /*
3055 * The check will be bogus if we restart from the
3056 * beginning of the AIL, so ASSERT that we don't.
3057 * We never should since we're holding the AIL lock
3058 * the entire time.
3059 */
3060 ASSERT(gen == orig_gen);
3061 } while (lip != NULL);
3062}
3063#endif /* DEBUG */
3064
3065/*
3066 * When this is called, all of the EFIs which did not have 3010 * When this is called, all of the EFIs which did not have
3067 * corresponding EFDs should be in the AIL. What we do now 3011 * corresponding EFDs should be in the AIL. What we do now
3068 * is free the extents associated with each one. 3012 * is free the extents associated with each one.
@@ -3086,20 +3030,23 @@ xlog_recover_process_efis(
3086{ 3030{
3087 xfs_log_item_t *lip; 3031 xfs_log_item_t *lip;
3088 xfs_efi_log_item_t *efip; 3032 xfs_efi_log_item_t *efip;
3089 int gen;
3090 xfs_mount_t *mp;
3091 int error = 0; 3033 int error = 0;
3034 struct xfs_ail_cursor cur;
3035 struct xfs_ail *ailp;
3092 3036
3093 mp = log->l_mp; 3037 ailp = log->l_ailp;
3094 spin_lock(&mp->m_ail_lock); 3038 spin_lock(&ailp->xa_lock);
3095 3039 lip = xfs_trans_ail_cursor_first(ailp, &cur, 0);
3096 lip = xfs_trans_first_ail(mp, &gen);
3097 while (lip != NULL) { 3040 while (lip != NULL) {
3098 /* 3041 /*
3099 * We're done when we see something other than an EFI. 3042 * We're done when we see something other than an EFI.
3043 * There should be no EFIs left in the AIL now.
3100 */ 3044 */
3101 if (lip->li_type != XFS_LI_EFI) { 3045 if (lip->li_type != XFS_LI_EFI) {
3102 xlog_recover_check_ail(mp, lip, gen); 3046#ifdef DEBUG
3047 for (; lip; lip = xfs_trans_ail_cursor_next(ailp, &cur))
3048 ASSERT(lip->li_type != XFS_LI_EFI);
3049#endif
3103 break; 3050 break;
3104 } 3051 }
3105 3052
@@ -3108,18 +3055,20 @@ xlog_recover_process_efis(
3108 */ 3055 */
3109 efip = (xfs_efi_log_item_t *)lip; 3056 efip = (xfs_efi_log_item_t *)lip;
3110 if (efip->efi_flags & XFS_EFI_RECOVERED) { 3057 if (efip->efi_flags & XFS_EFI_RECOVERED) {
3111 lip = xfs_trans_next_ail(mp, lip, &gen, NULL); 3058 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3112 continue; 3059 continue;
3113 } 3060 }
3114 3061
3115 spin_unlock(&mp->m_ail_lock); 3062 spin_unlock(&ailp->xa_lock);
3116 error = xlog_recover_process_efi(mp, efip); 3063 error = xlog_recover_process_efi(log->l_mp, efip);
3064 spin_lock(&ailp->xa_lock);
3117 if (error) 3065 if (error)
3118 return error; 3066 goto out;
3119 spin_lock(&mp->m_ail_lock); 3067 lip = xfs_trans_ail_cursor_next(ailp, &cur);
3120 lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
3121 } 3068 }
3122 spin_unlock(&mp->m_ail_lock); 3069out:
3070 xfs_trans_ail_cursor_done(ailp, &cur);
3071 spin_unlock(&ailp->xa_lock);
3123 return error; 3072 return error;
3124} 3073}
3125 3074
@@ -3140,19 +3089,16 @@ xlog_recover_clear_agi_bucket(
3140 int error; 3089 int error;
3141 3090
3142 tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); 3091 tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET);
3143 error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0); 3092 error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp),
3144 if (!error) 3093 0, 0, 0);
3145 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
3146 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
3147 XFS_FSS_TO_BB(mp, 1), 0, &agibp);
3148 if (error) 3094 if (error)
3149 goto out_abort; 3095 goto out_abort;
3150 3096
3151 error = EINVAL; 3097 error = xfs_read_agi(mp, tp, agno, &agibp);
3152 agi = XFS_BUF_TO_AGI(agibp); 3098 if (error)
3153 if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC)
3154 goto out_abort; 3099 goto out_abort;
3155 3100
3101 agi = XFS_BUF_TO_AGI(agibp);
3156 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); 3102 agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
3157 offset = offsetof(xfs_agi_t, agi_unlinked) + 3103 offset = offsetof(xfs_agi_t, agi_unlinked) +
3158 (sizeof(xfs_agino_t) * bucket); 3104 (sizeof(xfs_agino_t) * bucket);
@@ -3172,6 +3118,62 @@ out_error:
3172 return; 3118 return;
3173} 3119}
3174 3120
3121STATIC xfs_agino_t
3122xlog_recover_process_one_iunlink(
3123 struct xfs_mount *mp,
3124 xfs_agnumber_t agno,
3125 xfs_agino_t agino,
3126 int bucket)
3127{
3128 struct xfs_buf *ibp;
3129 struct xfs_dinode *dip;
3130 struct xfs_inode *ip;
3131 xfs_ino_t ino;
3132 int error;
3133
3134 ino = XFS_AGINO_TO_INO(mp, agno, agino);
3135 error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
3136 if (error)
3137 goto fail;
3138
3139 /*
3140 * Get the on disk inode to find the next inode in the bucket.
3141 */
3142 error = xfs_itobp(mp, NULL, ip, &dip, &ibp, XFS_BUF_LOCK);
3143 if (error)
3144 goto fail_iput;
3145
3146 ASSERT(ip->i_d.di_nlink == 0);
3147 ASSERT(ip->i_d.di_mode != 0);
3148
3149 /* setup for the next pass */
3150 agino = be32_to_cpu(dip->di_next_unlinked);
3151 xfs_buf_relse(ibp);
3152
3153 /*
3154 * Prevent any DMAPI event from being sent when the reference on
3155 * the inode is dropped.
3156 */
3157 ip->i_d.di_dmevmask = 0;
3158
3159 IRELE(ip);
3160 return agino;
3161
3162 fail_iput:
3163 IRELE(ip);
3164 fail:
3165 /*
3166 * We can't read in the inode this bucket points to, or this inode
3167 * is messed up. Just ditch this bucket of inodes. We will lose
3168 * some inodes and space, but at least we won't hang.
3169 *
3170 * Call xlog_recover_clear_agi_bucket() to perform a transaction to
3171 * clear the inode pointer in the bucket.
3172 */
3173 xlog_recover_clear_agi_bucket(mp, agno, bucket);
3174 return NULLAGINO;
3175}
3176
3175/* 3177/*
3176 * xlog_iunlink_recover 3178 * xlog_iunlink_recover
3177 * 3179 *
@@ -3192,11 +3194,7 @@ xlog_recover_process_iunlinks(
3192 xfs_agnumber_t agno; 3194 xfs_agnumber_t agno;
3193 xfs_agi_t *agi; 3195 xfs_agi_t *agi;
3194 xfs_buf_t *agibp; 3196 xfs_buf_t *agibp;
3195 xfs_buf_t *ibp;
3196 xfs_dinode_t *dip;
3197 xfs_inode_t *ip;
3198 xfs_agino_t agino; 3197 xfs_agino_t agino;
3199 xfs_ino_t ino;
3200 int bucket; 3198 int bucket;
3201 int error; 3199 int error;
3202 uint mp_dmevmask; 3200 uint mp_dmevmask;
@@ -3213,22 +3211,21 @@ xlog_recover_process_iunlinks(
3213 /* 3211 /*
3214 * Find the agi for this ag. 3212 * Find the agi for this ag.
3215 */ 3213 */
3216 agibp = xfs_buf_read(mp->m_ddev_targp, 3214 error = xfs_read_agi(mp, NULL, agno, &agibp);
3217 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 3215 if (error) {
3218 XFS_FSS_TO_BB(mp, 1), 0); 3216 /*
3219 if (XFS_BUF_ISERROR(agibp)) { 3217 * AGI is b0rked. Don't process it.
3220 xfs_ioerror_alert("xlog_recover_process_iunlinks(#1)", 3218 *
3221 log->l_mp, agibp, 3219 * We should probably mark the filesystem as corrupt
3222 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp))); 3220 * after we've recovered all the ag's we can....
3221 */
3222 continue;
3223 } 3223 }
3224 agi = XFS_BUF_TO_AGI(agibp); 3224 agi = XFS_BUF_TO_AGI(agibp);
3225 ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agi->agi_magicnum));
3226 3225
3227 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) { 3226 for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) {
3228
3229 agino = be32_to_cpu(agi->agi_unlinked[bucket]); 3227 agino = be32_to_cpu(agi->agi_unlinked[bucket]);
3230 while (agino != NULLAGINO) { 3228 while (agino != NULLAGINO) {
3231
3232 /* 3229 /*
3233 * Release the agi buffer so that it can 3230 * Release the agi buffer so that it can
3234 * be acquired in the normal course of the 3231 * be acquired in the normal course of the
@@ -3236,87 +3233,17 @@ xlog_recover_process_iunlinks(
3236 */ 3233 */
3237 xfs_buf_relse(agibp); 3234 xfs_buf_relse(agibp);
3238 3235
3239 ino = XFS_AGINO_TO_INO(mp, agno, agino); 3236 agino = xlog_recover_process_one_iunlink(mp,
3240 error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0); 3237 agno, agino, bucket);
3241 ASSERT(error || (ip != NULL));
3242
3243 if (!error) {
3244 /*
3245 * Get the on disk inode to find the
3246 * next inode in the bucket.
3247 */
3248 error = xfs_itobp(mp, NULL, ip, &dip,
3249 &ibp, 0, 0,
3250 XFS_BUF_LOCK);
3251 ASSERT(error || (dip != NULL));
3252 }
3253
3254 if (!error) {
3255 ASSERT(ip->i_d.di_nlink == 0);
3256
3257 /* setup for the next pass */
3258 agino = be32_to_cpu(
3259 dip->di_next_unlinked);
3260 xfs_buf_relse(ibp);
3261 /*
3262 * Prevent any DMAPI event from
3263 * being sent when the
3264 * reference on the inode is
3265 * dropped.
3266 */
3267 ip->i_d.di_dmevmask = 0;
3268
3269 /*
3270 * If this is a new inode, handle
3271 * it specially. Otherwise,
3272 * just drop our reference to the
3273 * inode. If there are no
3274 * other references, this will
3275 * send the inode to
3276 * xfs_inactive() which will
3277 * truncate the file and free
3278 * the inode.
3279 */
3280 if (ip->i_d.di_mode == 0)
3281 xfs_iput_new(ip, 0);
3282 else
3283 IRELE(ip);
3284 } else {
3285 /*
3286 * We can't read in the inode
3287 * this bucket points to, or
3288 * this inode is messed up. Just
3289 * ditch this bucket of inodes. We
3290 * will lose some inodes and space,
3291 * but at least we won't hang. Call
3292 * xlog_recover_clear_agi_bucket()
3293 * to perform a transaction to clear
3294 * the inode pointer in the bucket.
3295 */
3296 xlog_recover_clear_agi_bucket(mp, agno,
3297 bucket);
3298
3299 agino = NULLAGINO;
3300 }
3301 3238
3302 /* 3239 /*
3303 * Reacquire the agibuffer and continue around 3240 * Reacquire the agibuffer and continue around
3304 * the loop. 3241 * the loop. This should never fail as we know
3242 * the buffer was good earlier on.
3305 */ 3243 */
3306 agibp = xfs_buf_read(mp->m_ddev_targp, 3244 error = xfs_read_agi(mp, NULL, agno, &agibp);
3307 XFS_AG_DADDR(mp, agno, 3245 ASSERT(error == 0);
3308 XFS_AGI_DADDR(mp)),
3309 XFS_FSS_TO_BB(mp, 1), 0);
3310 if (XFS_BUF_ISERROR(agibp)) {
3311 xfs_ioerror_alert(
3312 "xlog_recover_process_iunlinks(#2)",
3313 log->l_mp, agibp,
3314 XFS_AG_DADDR(mp, agno,
3315 XFS_AGI_DADDR(mp)));
3316 }
3317 agi = XFS_BUF_TO_AGI(agibp); 3246 agi = XFS_BUF_TO_AGI(agibp);
3318 ASSERT(XFS_AGI_MAGIC == be32_to_cpu(
3319 agi->agi_magicnum));
3320 } 3247 }
3321 } 3248 }
3322 3249
@@ -3367,7 +3294,6 @@ xlog_pack_data(
3367 int size = iclog->ic_offset + roundoff; 3294 int size = iclog->ic_offset + roundoff;
3368 __be32 cycle_lsn; 3295 __be32 cycle_lsn;
3369 xfs_caddr_t dp; 3296 xfs_caddr_t dp;
3370 xlog_in_core_2_t *xhdr;
3371 3297
3372 xlog_pack_data_checksum(log, iclog, size); 3298 xlog_pack_data_checksum(log, iclog, size);
3373 3299
@@ -3382,7 +3308,8 @@ xlog_pack_data(
3382 } 3308 }
3383 3309
3384 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { 3310 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
3385 xhdr = (xlog_in_core_2_t *)&iclog->ic_header; 3311 xlog_in_core_2_t *xhdr = iclog->ic_data;
3312
3386 for ( ; i < BTOBB(size); i++) { 3313 for ( ; i < BTOBB(size); i++) {
3387 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); 3314 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3388 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); 3315 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
@@ -3440,7 +3367,6 @@ xlog_unpack_data(
3440 xlog_t *log) 3367 xlog_t *log)
3441{ 3368{
3442 int i, j, k; 3369 int i, j, k;
3443 xlog_in_core_2_t *xhdr;
3444 3370
3445 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && 3371 for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) &&
3446 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { 3372 i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) {
@@ -3449,7 +3375,7 @@ xlog_unpack_data(
3449 } 3375 }
3450 3376
3451 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) { 3377 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
3452 xhdr = (xlog_in_core_2_t *)rhead; 3378 xlog_in_core_2_t *xhdr = (xlog_in_core_2_t *)rhead;
3453 for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) { 3379 for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
3454 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE); 3380 j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3455 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE); 3381 k = i % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
@@ -4003,11 +3929,8 @@ xlog_recover_check_summary(
4003{ 3929{
4004 xfs_mount_t *mp; 3930 xfs_mount_t *mp;
4005 xfs_agf_t *agfp; 3931 xfs_agf_t *agfp;
4006 xfs_agi_t *agip;
4007 xfs_buf_t *agfbp; 3932 xfs_buf_t *agfbp;
4008 xfs_buf_t *agibp; 3933 xfs_buf_t *agibp;
4009 xfs_daddr_t agfdaddr;
4010 xfs_daddr_t agidaddr;
4011 xfs_buf_t *sbbp; 3934 xfs_buf_t *sbbp;
4012#ifdef XFS_LOUD_RECOVERY 3935#ifdef XFS_LOUD_RECOVERY
4013 xfs_sb_t *sbp; 3936 xfs_sb_t *sbp;
@@ -4016,6 +3939,7 @@ xlog_recover_check_summary(
4016 __uint64_t freeblks; 3939 __uint64_t freeblks;
4017 __uint64_t itotal; 3940 __uint64_t itotal;
4018 __uint64_t ifree; 3941 __uint64_t ifree;
3942 int error;
4019 3943
4020 mp = log->l_mp; 3944 mp = log->l_mp;
4021 3945
@@ -4023,37 +3947,27 @@ xlog_recover_check_summary(
4023 itotal = 0LL; 3947 itotal = 0LL;
4024 ifree = 0LL; 3948 ifree = 0LL;
4025 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { 3949 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
4026 agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)); 3950 error = xfs_read_agf(mp, NULL, agno, 0, &agfbp);
4027 agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr, 3951 if (error) {
4028 XFS_FSS_TO_BB(mp, 1), 0); 3952 xfs_fs_cmn_err(CE_ALERT, mp,
4029 if (XFS_BUF_ISERROR(agfbp)) { 3953 "xlog_recover_check_summary(agf)"
4030 xfs_ioerror_alert("xlog_recover_check_summary(agf)", 3954 "agf read failed agno %d error %d",
4031 mp, agfbp, agfdaddr); 3955 agno, error);
4032 } 3956 } else {
4033 agfp = XFS_BUF_TO_AGF(agfbp); 3957 agfp = XFS_BUF_TO_AGF(agfbp);
4034 ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum)); 3958 freeblks += be32_to_cpu(agfp->agf_freeblks) +
4035 ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum))); 3959 be32_to_cpu(agfp->agf_flcount);
4036 ASSERT(be32_to_cpu(agfp->agf_seqno) == agno); 3960 xfs_buf_relse(agfbp);
4037
4038 freeblks += be32_to_cpu(agfp->agf_freeblks) +
4039 be32_to_cpu(agfp->agf_flcount);
4040 xfs_buf_relse(agfbp);
4041
4042 agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp));
4043 agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr,
4044 XFS_FSS_TO_BB(mp, 1), 0);
4045 if (XFS_BUF_ISERROR(agibp)) {
4046 xfs_ioerror_alert("xlog_recover_check_summary(agi)",
4047 mp, agibp, agidaddr);
4048 } 3961 }
4049 agip = XFS_BUF_TO_AGI(agibp);
4050 ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agip->agi_magicnum));
4051 ASSERT(XFS_AGI_GOOD_VERSION(be32_to_cpu(agip->agi_versionnum)));
4052 ASSERT(be32_to_cpu(agip->agi_seqno) == agno);
4053 3962
4054 itotal += be32_to_cpu(agip->agi_count); 3963 error = xfs_read_agi(mp, NULL, agno, &agibp);
4055 ifree += be32_to_cpu(agip->agi_freecount); 3964 if (!error) {
4056 xfs_buf_relse(agibp); 3965 struct xfs_agi *agi = XFS_BUF_TO_AGI(agibp);
3966
3967 itotal += be32_to_cpu(agi->agi_count);
3968 ifree += be32_to_cpu(agi->agi_freecount);
3969 xfs_buf_relse(agibp);
3970 }
4057 } 3971 }
4058 3972
4059 sbbp = xfs_getsb(mp, 0); 3973 sbbp = xfs_getsb(mp, 0);