]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - scrub/progress.c
xfs_scrub: handle spurious wakeups in scan_fs_tree
[thirdparty/xfsprogs-dev.git] / scrub / progress.c
index 08c7233eef5094d4b4134bf090d6aa471ef1c4ee..a3d096f98e2c8548d9583aebd4f476ce30d9215e 100644 (file)
@@ -110,13 +110,13 @@ progress_report(
        fflush(pt.fp);
 }
 
-#define NSEC_PER_SEC   (1000000000)
 static void *
 progress_report_thread(void *arg)
 {
        struct timespec         abstime;
        int                     ret;
 
+       rcu_register_thread();
        pthread_mutex_lock(&pt.lock);
        while (1) {
                uint64_t        progress_val;
@@ -130,7 +130,9 @@ progress_report_thread(void *arg)
                        abstime.tv_sec++;
                        abstime.tv_nsec -= NSEC_PER_SEC;
                }
-               pthread_cond_timedwait(&pt.wakeup, &pt.lock, &abstime);
+               ret = pthread_cond_timedwait(&pt.wakeup, &pt.lock, &abstime);
+               if (ret && ret != ETIMEDOUT)
+                       break;
                if (pt.terminate)
                        break;
                ret = ptcounter_value(pt.ptc, &progress_val);
@@ -138,6 +140,7 @@ progress_report_thread(void *arg)
                        progress_report(progress_val);
        }
        pthread_mutex_unlock(&pt.lock);
+       rcu_unregister_thread();
        return NULL;
 }
 
@@ -165,8 +168,11 @@ progress_end_phase(void)
        pt.fp = NULL;
 }
 
-/* Set ourselves up to report progress. */
-bool
+/*
+ * Set ourselves up to report progress.  If errors are encountered, this
+ * function will log them and return nonzero.
+ */
+int
 progress_init_phase(
        struct scrub_ctx        *ctx,
        FILE                    *fp,
@@ -180,7 +186,7 @@ progress_init_phase(
        assert(pt.fp == NULL);
        if (fp == NULL || max == 0) {
                pt.fp = NULL;
-               return true;
+               return 0;
        }
        pt.fp = fp;
        pt.isatty = isatty(fileno(fp));
@@ -198,10 +204,12 @@ progress_init_phase(
        }
 
        ret = pthread_create(&pt.thread, NULL, progress_report_thread, NULL);
-       if (ret)
+       if (ret) {
+               str_liberror(ctx, ret, _("creating progress reporting thread"));
                goto out_ptcounter;
+       }
 
-       return true;
+       return 0;
 
 out_ptcounter:
        ptcounter_free(pt.ptc);
@@ -209,5 +217,5 @@ out_ptcounter:
 out_max:
        pt.max = 0;
        pt.fp = NULL;
-       return false;
+       return ret;
 }