diff options
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 171 |
1 files changed, 18 insertions, 153 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 39797490a1f1..b6b669df40f3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -17,42 +17,34 @@ | |||
17 | */ | 17 | */ |
18 | #include "xfs.h" | 18 | #include "xfs.h" |
19 | #include "xfs_fs.h" | 19 | #include "xfs_fs.h" |
20 | #include "xfs_shared.h" | ||
20 | #include "xfs_format.h" | 21 | #include "xfs_format.h" |
22 | #include "xfs_log_format.h" | ||
23 | #include "xfs_trans_resv.h" | ||
21 | #include "xfs_bit.h" | 24 | #include "xfs_bit.h" |
22 | #include "xfs_log.h" | ||
23 | #include "xfs_inum.h" | 25 | #include "xfs_inum.h" |
24 | #include "xfs_trans.h" | ||
25 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
27 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
28 | #include "xfs_error.h" | 29 | #include "xfs_da_format.h" |
29 | #include "xfs_bmap_btree.h" | ||
30 | #include "xfs_alloc_btree.h" | ||
31 | #include "xfs_ialloc_btree.h" | ||
32 | #include "xfs_btree.h" | ||
33 | #include "xfs_dinode.h" | ||
34 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
35 | #include "xfs_inode_item.h" | 31 | #include "xfs_trans.h" |
36 | #include "xfs_alloc.h" | 32 | #include "xfs_log.h" |
37 | #include "xfs_ialloc.h" | ||
38 | #include "xfs_log_priv.h" | 33 | #include "xfs_log_priv.h" |
39 | #include "xfs_buf_item.h" | ||
40 | #include "xfs_log_recover.h" | 34 | #include "xfs_log_recover.h" |
35 | #include "xfs_inode_item.h" | ||
41 | #include "xfs_extfree_item.h" | 36 | #include "xfs_extfree_item.h" |
42 | #include "xfs_trans_priv.h" | 37 | #include "xfs_trans_priv.h" |
38 | #include "xfs_alloc.h" | ||
39 | #include "xfs_ialloc.h" | ||
43 | #include "xfs_quota.h" | 40 | #include "xfs_quota.h" |
44 | #include "xfs_cksum.h" | 41 | #include "xfs_cksum.h" |
45 | #include "xfs_trace.h" | 42 | #include "xfs_trace.h" |
46 | #include "xfs_icache.h" | 43 | #include "xfs_icache.h" |
47 | #include "xfs_icreate_item.h" | 44 | #include "xfs_bmap_btree.h" |
48 | 45 | #include "xfs_dinode.h" | |
49 | /* Need all the magic numbers and buffer ops structures from these headers */ | 46 | #include "xfs_error.h" |
50 | #include "xfs_symlink.h" | ||
51 | #include "xfs_da_btree.h" | ||
52 | #include "xfs_dir2_format.h" | ||
53 | #include "xfs_dir2.h" | 47 | #include "xfs_dir2.h" |
54 | #include "xfs_attr_leaf.h" | ||
55 | #include "xfs_attr_remote.h" | ||
56 | 48 | ||
57 | #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) | 49 | #define BLK_AVG(blk1, blk2) ((blk1+blk2) >> 1) |
58 | 50 | ||
@@ -305,9 +297,9 @@ xlog_header_check_dump( | |||
305 | xfs_mount_t *mp, | 297 | xfs_mount_t *mp, |
306 | xlog_rec_header_t *head) | 298 | xlog_rec_header_t *head) |
307 | { | 299 | { |
308 | xfs_debug(mp, "%s: SB : uuid = %pU, fmt = %d\n", | 300 | xfs_debug(mp, "%s: SB : uuid = %pU, fmt = %d", |
309 | __func__, &mp->m_sb.sb_uuid, XLOG_FMT); | 301 | __func__, &mp->m_sb.sb_uuid, XLOG_FMT); |
310 | xfs_debug(mp, " log : uuid = %pU, fmt = %d\n", | 302 | xfs_debug(mp, " log : uuid = %pU, fmt = %d", |
311 | &head->h_fs_uuid, be32_to_cpu(head->h_fmt)); | 303 | &head->h_fs_uuid, be32_to_cpu(head->h_fmt)); |
312 | } | 304 | } |
313 | #else | 305 | #else |
@@ -2362,7 +2354,7 @@ xlog_recover_do_reg_buffer( | |||
2362 | item->ri_buf[i].i_len, __func__); | 2354 | item->ri_buf[i].i_len, __func__); |
2363 | goto next; | 2355 | goto next; |
2364 | } | 2356 | } |
2365 | error = xfs_qm_dqcheck(mp, item->ri_buf[i].i_addr, | 2357 | error = xfs_dqcheck(mp, item->ri_buf[i].i_addr, |
2366 | -1, 0, XFS_QMOPT_DOWARN, | 2358 | -1, 0, XFS_QMOPT_DOWARN, |
2367 | "dquot_buf_recover"); | 2359 | "dquot_buf_recover"); |
2368 | if (error) | 2360 | if (error) |
@@ -2394,133 +2386,6 @@ xlog_recover_do_reg_buffer( | |||
2394 | } | 2386 | } |
2395 | 2387 | ||
2396 | /* | 2388 | /* |
2397 | * Do some primitive error checking on ondisk dquot data structures. | ||
2398 | */ | ||
2399 | int | ||
2400 | xfs_qm_dqcheck( | ||
2401 | struct xfs_mount *mp, | ||
2402 | xfs_disk_dquot_t *ddq, | ||
2403 | xfs_dqid_t id, | ||
2404 | uint type, /* used only when IO_dorepair is true */ | ||
2405 | uint flags, | ||
2406 | char *str) | ||
2407 | { | ||
2408 | xfs_dqblk_t *d = (xfs_dqblk_t *)ddq; | ||
2409 | int errs = 0; | ||
2410 | |||
2411 | /* | ||
2412 | * We can encounter an uninitialized dquot buffer for 2 reasons: | ||
2413 | * 1. If we crash while deleting the quotainode(s), and those blks got | ||
2414 | * used for user data. This is because we take the path of regular | ||
2415 | * file deletion; however, the size field of quotainodes is never | ||
2416 | * updated, so all the tricks that we play in itruncate_finish | ||
2417 | * don't quite matter. | ||
2418 | * | ||
2419 | * 2. We don't play the quota buffers when there's a quotaoff logitem. | ||
2420 | * But the allocation will be replayed so we'll end up with an | ||
2421 | * uninitialized quota block. | ||
2422 | * | ||
2423 | * This is all fine; things are still consistent, and we haven't lost | ||
2424 | * any quota information. Just don't complain about bad dquot blks. | ||
2425 | */ | ||
2426 | if (ddq->d_magic != cpu_to_be16(XFS_DQUOT_MAGIC)) { | ||
2427 | if (flags & XFS_QMOPT_DOWARN) | ||
2428 | xfs_alert(mp, | ||
2429 | "%s : XFS dquot ID 0x%x, magic 0x%x != 0x%x", | ||
2430 | str, id, be16_to_cpu(ddq->d_magic), XFS_DQUOT_MAGIC); | ||
2431 | errs++; | ||
2432 | } | ||
2433 | if (ddq->d_version != XFS_DQUOT_VERSION) { | ||
2434 | if (flags & XFS_QMOPT_DOWARN) | ||
2435 | xfs_alert(mp, | ||
2436 | "%s : XFS dquot ID 0x%x, version 0x%x != 0x%x", | ||
2437 | str, id, ddq->d_version, XFS_DQUOT_VERSION); | ||
2438 | errs++; | ||
2439 | } | ||
2440 | |||
2441 | if (ddq->d_flags != XFS_DQ_USER && | ||
2442 | ddq->d_flags != XFS_DQ_PROJ && | ||
2443 | ddq->d_flags != XFS_DQ_GROUP) { | ||
2444 | if (flags & XFS_QMOPT_DOWARN) | ||
2445 | xfs_alert(mp, | ||
2446 | "%s : XFS dquot ID 0x%x, unknown flags 0x%x", | ||
2447 | str, id, ddq->d_flags); | ||
2448 | errs++; | ||
2449 | } | ||
2450 | |||
2451 | if (id != -1 && id != be32_to_cpu(ddq->d_id)) { | ||
2452 | if (flags & XFS_QMOPT_DOWARN) | ||
2453 | xfs_alert(mp, | ||
2454 | "%s : ondisk-dquot 0x%p, ID mismatch: " | ||
2455 | "0x%x expected, found id 0x%x", | ||
2456 | str, ddq, id, be32_to_cpu(ddq->d_id)); | ||
2457 | errs++; | ||
2458 | } | ||
2459 | |||
2460 | if (!errs && ddq->d_id) { | ||
2461 | if (ddq->d_blk_softlimit && | ||
2462 | be64_to_cpu(ddq->d_bcount) > | ||
2463 | be64_to_cpu(ddq->d_blk_softlimit)) { | ||
2464 | if (!ddq->d_btimer) { | ||
2465 | if (flags & XFS_QMOPT_DOWARN) | ||
2466 | xfs_alert(mp, | ||
2467 | "%s : Dquot ID 0x%x (0x%p) BLK TIMER NOT STARTED", | ||
2468 | str, (int)be32_to_cpu(ddq->d_id), ddq); | ||
2469 | errs++; | ||
2470 | } | ||
2471 | } | ||
2472 | if (ddq->d_ino_softlimit && | ||
2473 | be64_to_cpu(ddq->d_icount) > | ||
2474 | be64_to_cpu(ddq->d_ino_softlimit)) { | ||
2475 | if (!ddq->d_itimer) { | ||
2476 | if (flags & XFS_QMOPT_DOWARN) | ||
2477 | xfs_alert(mp, | ||
2478 | "%s : Dquot ID 0x%x (0x%p) INODE TIMER NOT STARTED", | ||
2479 | str, (int)be32_to_cpu(ddq->d_id), ddq); | ||
2480 | errs++; | ||
2481 | } | ||
2482 | } | ||
2483 | if (ddq->d_rtb_softlimit && | ||
2484 | be64_to_cpu(ddq->d_rtbcount) > | ||
2485 | be64_to_cpu(ddq->d_rtb_softlimit)) { | ||
2486 | if (!ddq->d_rtbtimer) { | ||
2487 | if (flags & XFS_QMOPT_DOWARN) | ||
2488 | xfs_alert(mp, | ||
2489 | "%s : Dquot ID 0x%x (0x%p) RTBLK TIMER NOT STARTED", | ||
2490 | str, (int)be32_to_cpu(ddq->d_id), ddq); | ||
2491 | errs++; | ||
2492 | } | ||
2493 | } | ||
2494 | } | ||
2495 | |||
2496 | if (!errs || !(flags & XFS_QMOPT_DQREPAIR)) | ||
2497 | return errs; | ||
2498 | |||
2499 | if (flags & XFS_QMOPT_DOWARN) | ||
2500 | xfs_notice(mp, "Re-initializing dquot ID 0x%x", id); | ||
2501 | |||
2502 | /* | ||
2503 | * Typically, a repair is only requested by quotacheck. | ||
2504 | */ | ||
2505 | ASSERT(id != -1); | ||
2506 | ASSERT(flags & XFS_QMOPT_DQREPAIR); | ||
2507 | memset(d, 0, sizeof(xfs_dqblk_t)); | ||
2508 | |||
2509 | d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); | ||
2510 | d->dd_diskdq.d_version = XFS_DQUOT_VERSION; | ||
2511 | d->dd_diskdq.d_flags = type; | ||
2512 | d->dd_diskdq.d_id = cpu_to_be32(id); | ||
2513 | |||
2514 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | ||
2515 | uuid_copy(&d->dd_uuid, &mp->m_sb.sb_uuid); | ||
2516 | xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), | ||
2517 | XFS_DQUOT_CRC_OFF); | ||
2518 | } | ||
2519 | |||
2520 | return errs; | ||
2521 | } | ||
2522 | |||
2523 | /* | ||
2524 | * Perform a dquot buffer recovery. | 2389 | * Perform a dquot buffer recovery. |
2525 | * Simple algorithm: if we have found a QUOTAOFF log item of the same type | 2390 | * Simple algorithm: if we have found a QUOTAOFF log item of the same type |
2526 | * (ie. USR or GRP), then just toss this buffer away; don't recover it. | 2391 | * (ie. USR or GRP), then just toss this buffer away; don't recover it. |
@@ -3125,7 +2990,7 @@ xlog_recover_dquot_pass2( | |||
3125 | */ | 2990 | */ |
3126 | dq_f = item->ri_buf[0].i_addr; | 2991 | dq_f = item->ri_buf[0].i_addr; |
3127 | ASSERT(dq_f); | 2992 | ASSERT(dq_f); |
3128 | error = xfs_qm_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, | 2993 | error = xfs_dqcheck(mp, recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, |
3129 | "xlog_recover_dquot_pass2 (log copy)"); | 2994 | "xlog_recover_dquot_pass2 (log copy)"); |
3130 | if (error) | 2995 | if (error) |
3131 | return XFS_ERROR(EIO); | 2996 | return XFS_ERROR(EIO); |
@@ -3145,7 +3010,7 @@ xlog_recover_dquot_pass2( | |||
3145 | * was among a chunk of dquots created earlier, and we did some | 3010 | * was among a chunk of dquots created earlier, and we did some |
3146 | * minimal initialization then. | 3011 | * minimal initialization then. |
3147 | */ | 3012 | */ |
3148 | error = xfs_qm_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, | 3013 | error = xfs_dqcheck(mp, ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, |
3149 | "xlog_recover_dquot_pass2"); | 3014 | "xlog_recover_dquot_pass2"); |
3150 | if (error) { | 3015 | if (error) { |
3151 | xfs_buf_relse(bp); | 3016 | xfs_buf_relse(bp); |
@@ -4077,7 +3942,7 @@ xlog_unpack_data_crc( | |||
4077 | if (crc != rhead->h_crc) { | 3942 | if (crc != rhead->h_crc) { |
4078 | if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { | 3943 | if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { |
4079 | xfs_alert(log->l_mp, | 3944 | xfs_alert(log->l_mp, |
4080 | "log record CRC mismatch: found 0x%x, expected 0x%x.\n", | 3945 | "log record CRC mismatch: found 0x%x, expected 0x%x.", |
4081 | le32_to_cpu(rhead->h_crc), | 3946 | le32_to_cpu(rhead->h_crc), |
4082 | le32_to_cpu(crc)); | 3947 | le32_to_cpu(crc)); |
4083 | xfs_hex_dump(dp, 32); | 3948 | xfs_hex_dump(dp, 32); |