]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
misc: add a crc32c self test to mkfs and repair
authorDarrick J. Wong <djwong@kernel.org>
Fri, 25 Feb 2022 22:37:56 +0000 (17:37 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 25 Feb 2022 22:37:56 +0000 (17:37 -0500)
Enhance mkfs and xfs_repair to run the crc32c self test when they start
up, and refuse to continue if the self test fails.   We don't want to
format a filesystem if the checksum algorithm produces incorrect
results, and we especially don't want repair to tear a filesystem apart
because it thinks the checksum is wrong.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
io/crc32cselftest.c
libfrog/crc32.c
libfrog/crc32cselftest.h
man/man8/mkfs.xfs.8
man/man8/xfs_repair.8
mkfs/xfs_mkfs.c
repair/init.c

index f8f757f6a7112e54d1d14cb073cce5efd28b5f53..49eb5b6d2b8b6cbe719d498447d158d9d0f0b665 100644 (file)
@@ -16,7 +16,7 @@ crc32cselftest_f(
        int             argc,
        char            **argv)
 {
-       return crc32c_test() != 0;
+       return crc32c_test(0) != 0;
 }
 
 static const cmdinfo_t crc32cselftest_cmd = {
index 6a273b715d13d9743d60603bb2ebe9870e6deab7..2499615df000405ee5bbe5fcca336139ee36f1e3 100644 (file)
@@ -202,7 +202,7 @@ int main(int argc, char **argv)
 
        printf("CRC_LE_BITS = %d\n", CRC_LE_BITS);
 
-       errors = crc32c_test();
+       errors = crc32c_test(0);
 
        return errors != 0;
 }
index 08284153c36cb4abfd4c91b3bb5a8fcb014cc313..447a7f7debe33ffc07f8b76678171e16f1141e5a 100644 (file)
@@ -661,18 +661,22 @@ static struct crc_test {
        {0xb18a0319, 0x00000026, 0x000007db, 0x9dc0bb48},
 };
 
+/* Don't print anything to stdout. */
+#define CRC32CTEST_QUIET       (1U << 0)
+
 static int
-crc32c_test(void)
+crc32c_test(
+       unsigned int    flags)
 {
-       int i;
-       int errors = 0;
-       int bytes = 0;
-       struct timeval start, stop;
-       uint64_t usec;
+       int             i;
+       int             errors = 0;
+       int             bytes = 0;
+       struct timeval  start, stop;
+       uint64_t        usec;
 
        /* keep static to prevent cache warming code from
         * getting eliminated by the compiler */
-       static uint32_t crc;
+       static uint32_t crc;
 
        /* pre-warm the cache */
        for (i = 0; i < 100; i++) {
@@ -693,6 +697,9 @@ crc32c_test(void)
        usec = stop.tv_usec - start.tv_usec +
                1000000 * (stop.tv_sec - start.tv_sec);
 
+       if (flags & CRC32CTEST_QUIET)
+               return errors;
+
        if (errors)
                printf("crc32c: %d self tests failed\n", errors);
        else {
index a7f70285dcd861e4045086a0d1a76228c6ce7613..880e949bbd92822ef5b19138e3b62c5a3127fe1c 100644 (file)
@@ -121,6 +121,10 @@ If the size of the block or sector is not specified, the default sizes
 .PP
 Many feature options allow an optional argument of 0 or 1, to explicitly
 disable or enable the functionality.
+
+The correctness of the crc32c checksum implementation will be tested
+before formatting the filesystem.
+If the test fails, the format will abort.
 .SH OPTIONS
 Options may be specified either on the command line or in a configuration file.
 Not all command line options can be specified in configuration files; only the
index cc6a2be8c03a412f3219dc0ccbf53a3c2b6ddf5a..6625b47adf5c82e748b55355670443b8b007f0fe 100644 (file)
@@ -184,6 +184,10 @@ usual 0. This option cannot be used together with
 .B \-V
 Prints the version number and exits.
 .SS Checks Performed
+The correctness of the crc32c checksum implementation will be tested
+before examining the filesystem.
+If the test fails, the program will abort.
+
 Inconsistencies corrected include the following:
 .IP 1.
 Inode and inode blockmap (addressing) checks:
index 057b3b0914b79e1fd8d2758acf0088a8ce12d6ac..3a41e17f855508a72e2fa5c7ae270db49f8f07ea 100644 (file)
@@ -10,6 +10,7 @@
 #include "libxcmd.h"
 #include "libfrog/fsgeom.h"
 #include "libfrog/convert.h"
+#include "libfrog/crc32cselftest.h"
 #include "proto.h"
 #include <ini.h>
 
@@ -4044,6 +4045,13 @@ main(
                        exit(0);
        }
 
+       /* Make sure our checksum algorithm really works. */
+       if (crc32c_test(CRC32CTEST_QUIET) != 0) {
+               fprintf(stderr,
+ _("crc32c self-test failed, will not create a filesystem here.\n"));
+               return 1;
+       }
+
        /*
         * All values have been validated, discard the old device layout.
         */
index 55f226e97a9da27e3d0025352d499d82dfc295e1..3a320b4ff6b0317c3ffbfa7be721cae554d00f62 100644 (file)
@@ -14,6 +14,7 @@
 #include "bmap.h"
 #include "incore.h"
 #include "prefetch.h"
+#include "libfrog/crc32cselftest.h"
 #include <sys/resource.h>
 
 static void
@@ -100,4 +101,8 @@ _("Unmount or use the dangerous (-d) option to repair a read-only mounted filesy
        ts_create();
        increase_rlimit();
        pftrace_init();
+
+       if (crc32c_test(CRC32CTEST_QUIET) != 0)
+               do_error(
+ _("crc32c self-test failed, will not examine filesystem.\n"));
 }