Commit d302cf1d316dca5f567e89872cf5d475c9a55f74

Authored by Dave Chinner
Committed by Ben Myers
1 parent 088c9f67c3

xfs: don't shutdown log recovery on validation errors

Unfortunately, we cannot guarantee that items logged multiple times
and replayed by log recovery do not take objects back in time. When
they are taken back in time, the go into an intermediate state which
is corrupt, and hence verification that occurs on this intermediate
state causes log recovery to abort with a corruption shutdown.

Instead of causing a shutdown and unmountable filesystem, don't
verify post-recovery items before they are written to disk. This is
less than optimal, but there is no way to detect this issue for
non-CRC filesystems If log recovery successfully completes, this
will be undone and the object will be consistent by subsequent
transactions that are replayed, so in most cases we don't need to
take drastic action.

For CRC enabled filesystems, leave the verifiers in place - we need
to call them to recalculate the CRCs on the objects anyway. This
recovery problem can be solved for such filesystems - we have a LSN
stamped in all metadata at writeback time that we can to determine
whether the item should be replayed or not. This is a separate piece
of work, so is not addressed by this patch.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>

(cherry picked from commit 9222a9cf86c0d64ffbedf567412b55da18763aa3)

Showing 1 changed file with 17 additions and 2 deletions Side-by-side Diff

fs/xfs/xfs_log_recover.c
... ... @@ -1845,8 +1845,14 @@
1845 1845 xfs_agino_t *buffer_nextp;
1846 1846  
1847 1847 trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f);
1848   - bp->b_ops = &xfs_inode_buf_ops;
1849 1848  
  1849 + /*
  1850 + * Post recovery validation only works properly on CRC enabled
  1851 + * filesystems.
  1852 + */
  1853 + if (xfs_sb_version_hascrc(&mp->m_sb))
  1854 + bp->b_ops = &xfs_inode_buf_ops;
  1855 +
1850 1856 inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog;
1851 1857 for (i = 0; i < inodes_per_buf; i++) {
1852 1858 next_unlinked_offset = (i * mp->m_sb.sb_inodesize) +
... ... @@ -2205,7 +2211,16 @@
2205 2211 /* Shouldn't be any more regions */
2206 2212 ASSERT(i == item->ri_total);
2207 2213  
2208   - xlog_recovery_validate_buf_type(mp, bp, buf_f);
  2214 + /*
  2215 + * We can only do post recovery validation on items on CRC enabled
  2216 + * fielsystems as we need to know when the buffer was written to be able
  2217 + * to determine if we should have replayed the item. If we replay old
  2218 + * metadata over a newer buffer, then it will enter a temporarily
  2219 + * inconsistent state resulting in verification failures. Hence for now
  2220 + * just avoid the verification stage for non-crc filesystems
  2221 + */
  2222 + if (xfs_sb_version_hascrc(&mp->m_sb))
  2223 + xlog_recovery_validate_buf_type(mp, bp, buf_f);
2209 2224 }
2210 2225  
2211 2226 /*