]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
repair: handle remote symlink CRC errors
authorDave Chinner <dchinner@redhat.com>
Thu, 1 May 2014 23:31:28 +0000 (09:31 +1000)
committerDave Chinner <david@fromorbit.com>
Thu, 1 May 2014 23:31:28 +0000 (09:31 +1000)
We can't really repair broken symlink buffer contents, but we can at
least warn about it and correct the CRC error so the symlink is
again readable.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
repair/dinode.c

index b086bec2d9b4ce122f4916884ab6d4d8bcd32649..8891e84ee7d234530c6a979763c9102af5595824 100644 (file)
@@ -1254,6 +1254,7 @@ process_symlink_remote(
        while (pathlen > 0) {
                int     blk_cnt = 1;
                int     byte_cnt;
+               int     badcrc = 0;
 
                fsbno = blkmap_get(blkmap, i);
                if (fsbno == NULLDFSBNO) {
@@ -1284,6 +1285,12 @@ _("cannot read inode %" PRIu64 ", file block %d, disk block %" PRIu64 "\n"),
                                lino, i, fsbno);
                        return 1;
                }
+               if (bp->b_error == EFSBADCRC) {
+                       do_warn(
+_("Bad symlink buffer CRC, block %" PRIu64 ", inode %" PRIu64 ".\n"
+  "Correcting CRC, but symlink may be bad.\n"), fsbno, lino);
+                       badcrc = 1;
+               }
 
                byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
                byte_cnt = MIN(pathlen, byte_cnt);
@@ -1307,7 +1314,10 @@ _("bad symlink header ino %" PRIu64 ", file block %d, disk block %" PRIu64 "\n")
                offset += byte_cnt;
                i++;
 
-               libxfs_putbuf(bp);
+               if (badcrc && !no_modify)
+                       libxfs_writebuf(bp, 0);
+               else
+                       libxfs_putbuf(bp);
        }
        return 0;
 }