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.c171
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 */
2399int
2400xfs_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);