aboutsummaryrefslogtreecommitdiffstats
path: root/scrub
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2019-09-26 13:45:56 -0400
committerEric Sandeen <sandeen@sandeen.net>2019-09-26 13:45:56 -0400
commit4953e7098af1e15dc554271e91b2e4491f4e22cc (patch)
tree42a8f88a9d465d50357b3c1097f8a7c6ee4160bc /scrub
parent83630b7ff9910501230c4154d52b6bc69112dc4a (diff)
downloadxfsprogs-dev-4953e7098af1e15dc554271e91b2e4491f4e22cc.tar.gz
xfs_scrub: fix nr_dirs accounting problems
When we're scanning the directory tree, we bump nr_dirs every time we think we're going to queue a new directory to process, and we decrement it every time we're finished doing something with a directory (successful or not). We forgot to undo a counter increment when workqueue_add fails, so refactor the code into helpers and call them as necessary for correct operation. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Diffstat (limited to 'scrub')
-rw-r--r--scrub/vfs.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/scrub/vfs.c b/scrub/vfs.c
index add4e81554..f8bc98c062 100644
--- a/scrub/vfs.c
+++ b/scrub/vfs.c
@@ -45,6 +45,32 @@ struct scan_fs_tree_dir {
static void scan_fs_dir(struct workqueue *wq, xfs_agnumber_t agno, void *arg);
+/* Increment the number of directories that are queued for processing. */
+static void
+inc_nr_dirs(
+ struct scan_fs_tree *sft)
+{
+ pthread_mutex_lock(&sft->lock);
+ sft->nr_dirs++;
+ pthread_mutex_unlock(&sft->lock);
+}
+
+/*
+ * Decrement the number of directories that are queued for processing and if
+ * we ran out of dirs to process, wake up anyone who was waiting for processing
+ * to finish.
+ */
+static void
+dec_nr_dirs(
+ struct scan_fs_tree *sft)
+{
+ pthread_mutex_lock(&sft->lock);
+ sft->nr_dirs--;
+ if (sft->nr_dirs == 0)
+ pthread_cond_signal(&sft->wakeup);
+ pthread_mutex_unlock(&sft->lock);
+}
+
/* Queue a directory for scanning. */
static bool
queue_subdir(
@@ -72,15 +98,10 @@ queue_subdir(
new_sftd->sft = sft;
new_sftd->rootdir = is_rootdir;
- pthread_mutex_lock(&sft->lock);
- sft->nr_dirs++;
- pthread_mutex_unlock(&sft->lock);
+ inc_nr_dirs(sft);
error = workqueue_add(wq, scan_fs_dir, 0, new_sftd);
if (error) {
- /*
- * XXX: need to decrement nr_dirs here; will do that in the
- * next patch.
- */
+ dec_nr_dirs(sft);
str_info(ctx, ctx->mntpoint,
_("Could not queue subdirectory scan work."));
goto out_path;
@@ -180,12 +201,7 @@ scan_fs_dir(
str_errno(ctx, sftd->path);
out:
- pthread_mutex_lock(&sft->lock);
- sft->nr_dirs--;
- if (sft->nr_dirs == 0)
- pthread_cond_signal(&sft->wakeup);
- pthread_mutex_unlock(&sft->lock);
-
+ dec_nr_dirs(sft);
free(sftd->path);
free(sftd);
}