lkml.org 
[lkml]   [2009]   [Jan]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH] Re: Corrupted XFS log replay oops.
    On Thu, Jan 22, 2009 at 01:11:58AM -0500, Christoph Hellwig wrote:
    > On Thu, Jan 22, 2009 at 03:37:47PM +1100, Dave Chinner wrote:
    > > xfs_buf_t *
    > > xlog_get_bp(
    > > xlog_t *log,
    > > - int num_bblks)
    > > + int nbblks)
    >
    > Any reason for reanming this variable? That causes quite a bit of
    > churn.
    >
    > > {
    > > - ASSERT(num_bblks > 0);
    > > + if (nbblks <= 0 || nbblks > log->l_logBBsize) {
    > > + xlog_warn("XFS: Invalid block length (0x%x) given for buffer", nbblks);
    >
    > And doesn't prevent this line from needing a linebreak to stay under 80
    > characters :)

    And now with line breaks.

    ------

    [XFS] Check buffer lengths in log recovery

    Before trying to obtain, read or write a buffer,
    check that the buffer length is actually valid. If
    it is not valid, then something read in the recovery
    process has been corrupted and we should abort
    recovery.

    Reported-by: Eric Sesterhenn <snakebyte@gmx.de>
    Signed-off-by: Dave Chinner <david@fromorbit.com>
    Tested-by: Eric Sesterhenn <snakebyte@gmx.de>
    ---
    fs/xfs/xfs_log_recover.c | 34 ++++++++++++++++++++++++++++------
    1 files changed, 28 insertions(+), 6 deletions(-)

    diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
    index 35cca98..a37e4aa 100644
    --- a/fs/xfs/xfs_log_recover.c
    +++ b/fs/xfs/xfs_log_recover.c
    @@ -70,16 +70,22 @@ STATIC void xlog_recover_check_summary(xlog_t *);
    xfs_buf_t *
    xlog_get_bp(
    xlog_t *log,
    - int num_bblks)
    + int nbblks)
    {
    - ASSERT(num_bblks > 0);
    + if (nbblks <= 0 || nbblks > log->l_logBBsize) {
    + xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
    + nbblks);
    + XFS_ERROR_REPORT("xlog_get_bp(1)",
    + XFS_ERRLEVEL_HIGH, log->l_mp);
    + return NULL;
    + }

    if (log->l_sectbb_log) {
    - if (num_bblks > 1)
    - num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
    - num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
    + if (nbblks > 1)
    + nbblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
    + nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
    }
    - return xfs_buf_get_noaddr(BBTOB(num_bblks), log->l_mp->m_logdev_targp);
    + return xfs_buf_get_noaddr(BBTOB(nbblks), log->l_mp->m_logdev_targp);
    }

    void
    @@ -102,6 +108,14 @@ xlog_bread(
    {
    int error;

    + if (nbblks <= 0 || nbblks > log->l_logBBsize) {
    + xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
    + nbblks);
    + XFS_ERROR_REPORT("xlog_bread(1)",
    + XFS_ERRLEVEL_HIGH, log->l_mp);
    + return EFSCORRUPTED;
    + }
    +
    if (log->l_sectbb_log) {
    blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
    nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
    @@ -139,6 +153,14 @@ xlog_bwrite(
    {
    int error;

    + if (nbblks <= 0 || nbblks > log->l_logBBsize) {
    + xlog_warn("XFS: Invalid block length (0x%x) given for buffer",
    + nbblks);
    + XFS_ERROR_REPORT("xlog_bwrite(1)",
    + XFS_ERRLEVEL_HIGH, log->l_mp);
    + return EFSCORRUPTED;
    + }
    +
    if (log->l_sectbb_log) {
    blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
    nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);

    \
     
     \ /
      Last update: 2009-01-23 01:05    [W:0.042 / U:2.032 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site