]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - scrub/common.c
misc: add static to various sourcefile-local functions
[thirdparty/xfsprogs-dev.git] / scrub / common.c
index 96b86a26e75282966cb6c7db73e4d607deffa294..49a87f412c4dcf65753d37ca73e6f679da5dc4f1 100644 (file)
@@ -8,7 +8,7 @@
 #include <sys/statvfs.h>
 #include <syslog.h>
 #include "platform_defs.h"
-#include "path.h"
+#include "libfrog/paths.h"
 #include "xfs_scrub.h"
 #include "common.h"
 #include "progress.h"
@@ -30,27 +30,57 @@ extern char         *progname;
 
 /* Too many errors? Bail out. */
 bool
-xfs_scrub_excessive_errors(
+scrub_excessive_errors(
        struct scrub_ctx        *ctx)
 {
-       bool                    ret;
+       unsigned long long      errors_seen;
+
+       /*
+        * We only set max_errors at the start of the program, so it's safe to
+        * access it locklessly.
+        */
+       if (ctx->max_errors == 0)
+               return false;
 
        pthread_mutex_lock(&ctx->lock);
-       ret = ctx->max_errors > 0 && ctx->errors_found >= ctx->max_errors;
+       errors_seen = ctx->corruptions_found + ctx->unfixable_errors;
        pthread_mutex_unlock(&ctx->lock);
 
-       return ret;
+       return errors_seen >= ctx->max_errors;
 }
 
 static struct {
        const char *string;
        int loglevel;
 } err_levels[] = {
-       [S_ERROR]  = { .string = "Error",       .loglevel = LOG_ERR },
-       [S_WARN]   = { .string = "Warning",     .loglevel = LOG_WARNING },
-       [S_REPAIR] = { .string = "Repaired",    .loglevel = LOG_WARNING },
-       [S_INFO]   = { .string = "Info",        .loglevel = LOG_INFO },
-       [S_PREEN]  = { .string = "Optimized",   .loglevel = LOG_INFO }
+       [S_ERROR]  = {
+               .string = "Error",
+               .loglevel = LOG_ERR,
+       },
+       [S_CORRUPT] = {
+               .string = "Corruption",
+               .loglevel = LOG_ERR,
+       },
+       [S_UNFIXABLE] = {
+               .string = "Unfixable Error",
+               .loglevel = LOG_ERR,
+       },
+       [S_WARN]   = {
+               .string = "Warning",
+               .loglevel = LOG_WARNING,
+       },
+       [S_INFO]   = {
+               .string = "Info",
+               .loglevel = LOG_INFO,
+       },
+       [S_REPAIR] = {
+               .string = "Repaired",
+               .loglevel = LOG_INFO,
+       },
+       [S_PREEN]  = {
+               .string = "Optimized",
+               .loglevel = LOG_INFO,
+       },
 };
 
 /* If stream is a tty, clear to end of line to clean up progress bar. */
@@ -106,10 +136,12 @@ __str_out(
                fflush(stream);
 
 out_record:
-       if (error)      /* A syscall failed */
+       if (error || level == S_ERROR)      /* A syscall failed */
                ctx->runtime_errors++;
-       else if (level == S_ERROR)
-               ctx->errors_found++;
+       else if (level == S_CORRUPT)
+               ctx->corruptions_found++;
+       else if (level == S_UNFIXABLE)
+               ctx->unfixable_errors++;
        else if (level == S_WARN)
                ctx->warnings_found++;
        else if (level == S_REPAIR)
@@ -200,10 +232,12 @@ no_prefix:
 double
 auto_units(
        unsigned long long      number,
-       char                    **units)
+       char                    **units,
+       int                     *precision)
 {
        if (debug > 1)
                goto no_prefix;
+       *precision = 1;
        if (number > 1000000000000ULL) {
                *units = "T";
                return number / 1000000000000.0;
@@ -220,6 +254,7 @@ auto_units(
 
 no_prefix:
        *units = "";
+       *precision = 0;
        return number;
 }
 
@@ -228,8 +263,8 @@ unsigned int
 scrub_nproc(
        struct scrub_ctx        *ctx)
 {
-       if (nr_threads)
-               return nr_threads;
+       if (force_nr_threads)
+               return force_nr_threads;
        return ctx->nr_io_threads;
 }
 
@@ -250,21 +285,21 @@ scrub_nproc_workqueue(
 }
 
 /*
- * Sleep for 100ms * however many -b we got past the initial one.
+ * Sleep for 100us * however many -b we got past the initial one.
  * This is an (albeit clumsy) way to throttle scrub activity.
  */
 void
 background_sleep(void)
 {
-       unsigned long long      time;
+       unsigned long long      time_ns;
        struct timespec         tv;
 
        if (bg_mode < 2)
                return;
 
-       time = 100000ULL * (bg_mode - 1);
-       tv.tv_sec = time / 1000000;
-       tv.tv_nsec = time % 1000000;
+       time_ns =  100 * NSEC_PER_USEC * (bg_mode - 1);
+       tv.tv_sec = time_ns / NSEC_PER_SEC;
+       tv.tv_nsec = time_ns % NSEC_PER_SEC;
        nanosleep(&tv, NULL);
 }
 
@@ -349,3 +384,38 @@ within_range(
 
        return true;
 }
+
+/*
+ * Render an inode number into a buffer in a format suitable for use in
+ * log messages. The buffer will be filled with:
+ *     "inode <inode number> (<ag number>/<ag inode number>)"
+ * If the @format argument is non-NULL, it will be rendered into the buffer
+ * after the inode representation and a single space.
+ */
+int
+scrub_render_ino_descr(
+       const struct scrub_ctx  *ctx,
+       char                    *buf,
+       size_t                  buflen,
+       uint64_t                ino,
+       uint32_t                gen,
+       const char              *format,
+       ...)
+{
+       va_list                 args;
+       uint32_t                agno;
+       uint32_t                agino;
+       int                     ret;
+
+       agno = cvt_ino_to_agno(&ctx->mnt, ino);
+       agino = cvt_ino_to_agino(&ctx->mnt, ino);
+       ret = snprintf(buf, buflen, _("inode %"PRIu64" (%"PRIu32"/%"PRIu32")%s"),
+                       ino, agno, agino, format ? " " : "");
+       if (ret < 0 || ret >= buflen || format == NULL)
+               return ret;
+
+       va_start(args, format);
+       ret += vsnprintf(buf + ret, buflen - ret, format, args);
+       va_end(args);
+       return ret;
+}