xfs: Wrapped journal record corruption on read at recovery
authorAndy Poling <andy@realbig.com>
Tue, 3 Nov 2009 17:26:47 +0000 (17:26 +0000)
committerAlex Elder <aelder@sgi.com>
Fri, 11 Dec 2009 21:11:21 +0000 (15:11 -0600)
commitfc5bc4c85c45f0bf854404e5736aa8b65720a18d
treef7938c5a4386a789606654e83f5dbb91367ef507
parent5ec4fabb02fcb5b4a4154a27e4299af5aa0f87ac
xfs: Wrapped journal record corruption on read at recovery

Summary of problem:

If a journal record wraps at the physical end of the journal, it has to be
read in two parts in xlog_do_recovery_pass(): a read at the physical end and a
read at the physical beginning.  If xlog_bread() has to re-align the first
read, the second read request does not take that re-alignment into account.
If the first read was re-aligned, the second read over-writes the end of the
data from the first read, effectively corrupting it.  This can happen either
when reading the record header or reading the record data.

The first sanity check in xlog_recover_process_data() is to check for a valid
clientid, so that is the error reported.

Summary of fix:

If there was a first read at the physical end, XFS_BUF_PTR() returns where the
data was requested to begin.  Conversely, because it is the result of
xlog_align(), offset indicates where the requested data for the first read
actually begins - whether or not xlog_bread() has re-aligned it.

Using offset as the base for the calculation of where to place the second read
data ensures that it will be correctly placed immediately following the data
from the first read instead of sometimes over-writing the end of it.

The attached patch has resolved the reported problem of occasional inability
to recover the journal (reporting "bad clientid").

Signed-off-by: Andy Poling <andy@realbig.com>
Reviewed-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
fs/xfs/xfs_log_recover.c