diff options
-rw-r--r-- | fs/xfs/xfs_log.c | 32 | ||||
-rw-r--r-- | fs/xfs/xfs_log_priv.h | 1 |
2 files changed, 25 insertions, 8 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 24643169e632..b612ce4520ae 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -3407,6 +3407,17 @@ xlog_verify_dest_ptr( | |||
3407 | xfs_emerg(log->l_mp, "%s: invalid ptr", __func__); | 3407 | xfs_emerg(log->l_mp, "%s: invalid ptr", __func__); |
3408 | } | 3408 | } |
3409 | 3409 | ||
3410 | /* | ||
3411 | * Check to make sure the grant write head didn't just over lap the tail. If | ||
3412 | * the cycles are the same, we can't be overlapping. Otherwise, make sure that | ||
3413 | * the cycles differ by exactly one and check the byte count. | ||
3414 | * | ||
3415 | * This check is run unlocked, so can give false positives. Rather than assert | ||
3416 | * on failures, use a warn-once flag and a panic tag to allow the admin to | ||
3417 | * determine if they want to panic the machine when such an error occurs. For | ||
3418 | * debug kernels this will have the same effect as using an assert but, unlinke | ||
3419 | * an assert, it can be turned off at runtime. | ||
3420 | */ | ||
3410 | STATIC void | 3421 | STATIC void |
3411 | xlog_verify_grant_tail( | 3422 | xlog_verify_grant_tail( |
3412 | struct log *log) | 3423 | struct log *log) |
@@ -3414,17 +3425,22 @@ xlog_verify_grant_tail( | |||
3414 | int tail_cycle, tail_blocks; | 3425 | int tail_cycle, tail_blocks; |
3415 | int cycle, space; | 3426 | int cycle, space; |
3416 | 3427 | ||
3417 | /* | ||
3418 | * Check to make sure the grant write head didn't just over lap the | ||
3419 | * tail. If the cycles are the same, we can't be overlapping. | ||
3420 | * Otherwise, make sure that the cycles differ by exactly one and | ||
3421 | * check the byte count. | ||
3422 | */ | ||
3423 | xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space); | 3428 | xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space); |
3424 | xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_blocks); | 3429 | xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_blocks); |
3425 | if (tail_cycle != cycle) { | 3430 | if (tail_cycle != cycle) { |
3426 | ASSERT(cycle - 1 == tail_cycle); | 3431 | if (cycle - 1 != tail_cycle && |
3427 | ASSERT(space <= BBTOB(tail_blocks)); | 3432 | !(log->l_flags & XLOG_TAIL_WARN)) { |
3433 | xfs_alert_tag(log->l_mp, XFS_PTAG_LOGRES, | ||
3434 | "%s: cycle - 1 != tail_cycle", __func__); | ||
3435 | log->l_flags |= XLOG_TAIL_WARN; | ||
3436 | } | ||
3437 | |||
3438 | if (space > BBTOB(tail_blocks) && | ||
3439 | !(log->l_flags & XLOG_TAIL_WARN)) { | ||
3440 | xfs_alert_tag(log->l_mp, XFS_PTAG_LOGRES, | ||
3441 | "%s: space > BBTOB(tail_blocks)", __func__); | ||
3442 | log->l_flags |= XLOG_TAIL_WARN; | ||
3443 | } | ||
3428 | } | 3444 | } |
3429 | } | 3445 | } |
3430 | 3446 | ||
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 15dbf1f9c2be..bc988d4ef958 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h | |||
@@ -144,6 +144,7 @@ static inline uint xlog_get_client_id(__be32 i) | |||
144 | #define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */ | 144 | #define XLOG_RECOVERY_NEEDED 0x4 /* log was recovered */ |
145 | #define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being | 145 | #define XLOG_IO_ERROR 0x8 /* log hit an I/O error, and being |
146 | shutdown */ | 146 | shutdown */ |
147 | #define XLOG_TAIL_WARN 0x10 /* log tail verify warning issued */ | ||
147 | 148 | ||
148 | #ifdef __KERNEL__ | 149 | #ifdef __KERNEL__ |
149 | /* | 150 | /* |