]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: fix broken EFSBADCRC/EFSCORRUPTED usage with buffer errors
authorDarrick J. Wong <djwong@alder.djwong.org>
Sun, 23 Aug 2015 23:21:01 +0000 (09:21 +1000)
committerDave Chinner <david@fromorbit.com>
Sun, 23 Aug 2015 23:21:01 +0000 (09:21 +1000)
When we encounter CRC or verifier errors, bp->b_error is set to
-EFSBADCRC and -EFSCORRUPTED; note the negative sign.  For whatever
reason, repair and db use the positive versions, and therefore fail to
notice the error, so fix all the broken uses.

Note however that the db and repair turn the negative codes returned
by libxfs into positive codes that can be used with strerror.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
db/attr.c
db/dir2.c
db/io.c
db/io.h
repair/dir2.c
repair/scan.c

index 897834b5f1cb6ddc9540931faa1282ec83c4694e..5e691005b758749f205b7c5250e517d7795d9005 100644 (file)
--- a/db/attr.c
+++ b/db/attr.c
@@ -554,7 +554,7 @@ xfs_attr3_db_read_verify(
                break;
        default:
                dbprintf(_("Unknown attribute buffer type!\n"));
-               xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_buf_ioerror(bp, -EFSCORRUPTED);
                return;
        }
 verify:
@@ -566,7 +566,7 @@ xfs_attr3_db_write_verify(
        struct xfs_buf          *bp)
 {
        dbprintf(_("Writing unknown attribute buffer type!\n"));
-       xfs_buf_ioerror(bp, EFSCORRUPTED);
+       xfs_buf_ioerror(bp, -EFSCORRUPTED);
 }
 
 const struct xfs_buf_ops xfs_attr3_db_buf_ops = {
index 7f69e6f6cdeecf0328d0041e048b65473e57f2dd..cc7666270c7df1b1c7034514cd1843c917d4ceed 100644 (file)
--- a/db/dir2.c
+++ b/db/dir2.c
@@ -1021,7 +1021,7 @@ xfs_dir3_db_read_verify(
                break;
        default:
                dbprintf(_("Unknown directory buffer type!\n"));
-               xfs_buf_ioerror(bp, EFSCORRUPTED);
+               xfs_buf_ioerror(bp, -EFSCORRUPTED);
                return;
        }
 verify:
@@ -1033,7 +1033,7 @@ xfs_dir3_db_write_verify(
        struct xfs_buf          *bp)
 {
        dbprintf(_("Writing unknown directory buffer type!\n"));
-       xfs_buf_ioerror(bp, EFSCORRUPTED);
+       xfs_buf_ioerror(bp, -EFSCORRUPTED);
 }
 
 const struct xfs_buf_ops xfs_dir3_db_buf_ops = {
diff --git a/db/io.c b/db/io.c
index 9fa52b880c1a197254686e7ac8fe33c224a1bce3..9452e072e95ff5e5de34ef43e652f47e8b3731b5 100644 (file)
--- a/db/io.c
+++ b/db/io.c
@@ -535,8 +535,8 @@ set_cur(
         * Keep the buffer even if the verifier says it is corrupted.
         * We're a diagnostic tool, after all.
         */
-       if (!bp || (bp->b_error && bp->b_error != EFSCORRUPTED &&
-                                  bp->b_error != EFSBADCRC))
+       if (!bp || (bp->b_error && bp->b_error != -EFSCORRUPTED &&
+                                  bp->b_error != -EFSBADCRC))
                return;
        iocur_top->buf = bp->b_addr;
        iocur_top->bp = bp;
diff --git a/db/io.h b/db/io.h
index 31d96b497c77d5637ec2712335dc9236e50a0cc2..6201d7b7e1163421c53f4743670daa187f8467f7 100644 (file)
--- a/db/io.h
+++ b/db/io.h
@@ -75,6 +75,6 @@ iocur_crc_valid()
                return -1;
        if (iocur_top->bp->b_flags & LIBXFS_B_UNCHECKED)
                return -1;
-       return (iocur_top->bp->b_error != EFSBADCRC &&
+       return (iocur_top->bp->b_error != -EFSBADCRC &&
                (!iocur_top->ino_buf || iocur_top->ino_crc_ok));
 }
index 187e069cea78ebc0465c45ef3c38abff0a9932ed..a5646f88477a474a5eaa9a92b7e5667d54522b41 100644 (file)
@@ -199,7 +199,7 @@ _("bad dir magic number 0x%x in inode %" PRIu64 " bno = %u\n"),
                        goto error_out;
                }
                /* corrupt node; rebuild the dir. */
-               if (bp->b_error == EFSBADCRC || bp->b_error == EFSCORRUPTED) {
+               if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
                        do_warn(
 _("corrupt tree block %u for directory inode %" PRIu64 "\n"),
                                bno, da_cursor->ino);
index 58f45eb91fe2e446613020a59aa30eb68160cddb..1e7a4da15609eaab28481330b46a7d4bbb0b3b73 100644 (file)
@@ -82,7 +82,7 @@ scan_sbtree(
                do_error(_("can't read btree block %d/%d\n"), agno, root);
                return;
        }
-       if (bp->b_error == EFSBADCRC || bp->b_error == EFSCORRUPTED) {
+       if (bp->b_error == -EFSBADCRC || bp->b_error == -EFSCORRUPTED) {
                do_warn(_("btree block %d/%d is suspect, error %d\n"),
                        agno, root, bp->b_error);
                suspect = 1;
@@ -145,7 +145,7 @@ scan_lbtree(
         * is a corruption or not and whether it got corrected and so needs
         * writing back. CRC errors always imply we need to write the block.
         */
-       if (bp->b_error == EFSBADCRC) {
+       if (bp->b_error == -EFSBADCRC) {
                do_warn(_("btree block %d/%d is suspect, error %d\n"),
                        XFS_FSB_TO_AGNO(mp, root),
                        XFS_FSB_TO_AGBNO(mp, root), bp->b_error);
@@ -1432,7 +1432,7 @@ scan_freelist(
                do_abort(_("can't read agfl block for ag %d\n"), agno);
                return;
        }
-       if (agflbuf->b_error == EFSBADCRC)
+       if (agflbuf->b_error == -EFSBADCRC)
                do_warn(_("agfl has bad CRC for ag %d\n"), agno);
 
        freelist = XFS_BUF_TO_AGFL_BNO(mp, agflbuf);
@@ -1705,9 +1705,9 @@ scan_ag(
         * immediately, though.
         */
        if (!no_modify) {
-               agi_dirty += (agibuf->b_error == EFSBADCRC);
-               agf_dirty += (agfbuf->b_error == EFSBADCRC);
-               sb_dirty += (sbbuf->b_error == EFSBADCRC);
+               agi_dirty += (agibuf->b_error == -EFSBADCRC);
+               agf_dirty += (agfbuf->b_error == -EFSBADCRC);
+               sb_dirty += (sbbuf->b_error == -EFSBADCRC);
        }
 
        if (agi_dirty && !no_modify)