Skip to content
  • Brian Foster's avatar
    xfs: remove invalid log recovery first/last cycle check · ec2ed0b5
    Brian Foster authored
    
    
    One of the first steps of log recovery is to check for the special
    case of a zeroed log. If the first cycle in the log is zero or the
    tail portion of the log is zeroed, the head is set to the first
    instance of cycle 0. xlog_find_zeroed() includes a sanity check that
    enforces that the first cycle in the log must be 1 if the last cycle
    is 0. While this is true in most cases, the check is not totally
    valid because it doesn't consider the case where the filesystem
    crashed after a partial/out of order log buffer completion that
    wraps around the end of the physical log.
    
    For example, consider a filesystem that has completed most of the
    first cycle of the log, reaches the end of the physical log and
    splits the next single log buffer write into two in order to wrap
    around the end of the log. If these I/Os are reordered, the second
    (wrapped) I/O completes and the first happens to fail, the log is
    left in a state where the last cycle of the log is 0 and the first
    cycle is 2. This causes the xlog_find_zeroed() sanity check to fail
    and prevents the filesystem from mounting. This situation has been
    reproduced on particular systems via repeated runs of generic/475.
    
    This is an expected state that log recovery already knows how to
    deal with, however. Since the log is still partially zeroed, the
    head is detected correctly and points to a valid tail. The
    subsequent stale block detection clears blocks beyond the head up to
    the tail (within a maximum range), with the express purpose of
    clearing such out of order writes. As expected, this removes the out
    of order cycle 2 blocks at the physical start of the log.
    
    In other words, the only thing that prevents a clean mount and
    recovery of the filesystem in this scenario is the specific (last ==
    0 && first != 1) sanity check in xlog_find_zeroed(). Since the log
    head/tail are now independently validated via cycle, log record and
    CRC checks, this highly specific first cycle check is of dubious
    value. Remove it and rely on the higher level validation to
    determine whether log content is sane and recoverable.
    
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    
    ec2ed0b5