@@ -28,6 +28,14 @@ struct scan_ctl {
pthread_mutex_t rbm_waitlock;
bool rbm_done;
+ /*
+ * Control mechanism to signal that each group's scan of the rt bitmap
+ * file scan is done and wake up any waiters.
+ */
+ pthread_cond_t rbm_group_wait;
+ pthread_mutex_t rbm_group_waitlock;
+ unsigned int rbm_group_count;
+
bool aborted;
};
@@ -178,6 +186,48 @@ scan_metafile(
}
}
+/* Scrub each rt group's metadata. */
+static void
+scan_rtgroup_metadata(
+ struct workqueue *wq,
+ xfs_agnumber_t rgno,
+ void *arg)
+{
+ struct scrub_item sri;
+ struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
+ struct scan_ctl *sctl = arg;
+ char descr[DESCR_BUFSZ];
+ int ret;
+
+ if (sctl->aborted)
+ goto out;
+
+ scrub_item_init_rtgroup(&sri, rgno);
+ snprintf(descr, DESCR_BUFSZ, _("rtgroup %u"), rgno);
+
+ scrub_item_schedule_group(&sri, XFROG_SCRUB_GROUP_RTGROUP);
+ ret = scrub_item_check(ctx, &sri);
+ if (ret) {
+ sctl->aborted = true;
+ goto out;
+ }
+
+ /* Everything else gets fixed during phase 4. */
+ ret = defer_fs_repair(ctx, &sri);
+ if (ret) {
+ sctl->aborted = true;
+ goto out;
+ }
+
+out:
+ /* Signal anybody waiting for the group bitmap scan to finish. */
+ pthread_mutex_lock(&sctl->rbm_group_waitlock);
+ sctl->rbm_group_count--;
+ if (sctl->rbm_group_count == 0)
+ pthread_cond_broadcast(&sctl->rbm_group_wait);
+ pthread_mutex_unlock(&sctl->rbm_group_waitlock);
+}
+
/* Scan all filesystem metadata. */
int
phase2_func(
@@ -191,6 +241,7 @@ phase2_func(
struct scrub_item sri;
const struct xfrog_scrub_descr *sc = xfrog_scrubbers;
xfs_agnumber_t agno;
+ xfs_rgnumber_t rgno;
unsigned int type;
int ret, ret2;
@@ -256,8 +307,10 @@ phase2_func(
goto out_wq;
/*
- * Wait for the rt bitmap to finish scanning, then scan the rt summary
- * since the summary can be regenerated completely from the bitmap.
+ * Wait for the rt bitmap to finish scanning, then scan the realtime
+ * group metadata. When rtgroups are enabled, the RTBITMAP scanner
+ * only checks the inode and fork data of the rt bitmap file, and each
+ * group checks its own part of the rtbitmap.
*/
ret = pthread_mutex_lock(&sctl.rbm_waitlock);
if (ret) {
@@ -274,6 +327,46 @@ phase2_func(
}
pthread_mutex_unlock(&sctl.rbm_waitlock);
+ if (sctl.aborted)
+ goto out_wq;
+
+ for (rgno = 0;
+ rgno < ctx->mnt.fsgeom.rgcount && !sctl.aborted;
+ rgno++) {
+ pthread_mutex_lock(&sctl.rbm_group_waitlock);
+ sctl.rbm_group_count++;
+ pthread_mutex_unlock(&sctl.rbm_group_waitlock);
+ ret = -workqueue_add(&wq, scan_rtgroup_metadata, rgno, &sctl);
+ if (ret) {
+ str_liberror(ctx, ret,
+ _("queueing rtgroup scrub work"));
+ goto out_wq;
+ }
+ }
+
+ if (sctl.aborted)
+ goto out_wq;
+
+ /*
+ * Wait for the rtgroups to finish scanning, then scan the rt summary
+ * since the summary can be regenerated completely from the bitmap.
+ */
+ ret = pthread_mutex_lock(&sctl.rbm_group_waitlock);
+ if (ret) {
+ str_liberror(ctx, ret, _("waiting for rtgroup scrubbers"));
+ goto out_wq;
+ }
+ if (sctl.rbm_group_count > 0) {
+ ret = pthread_cond_wait(&sctl.rbm_group_wait,
+ &sctl.rbm_group_waitlock);
+ if (ret) {
+ str_liberror(ctx, ret,
+ _("waiting for rtgroup scrubbers"));
+ goto out_wq;
+ }
+ }
+ pthread_mutex_unlock(&sctl.rbm_group_waitlock);
+
if (sctl.aborted)
goto out_wq;
@@ -87,6 +87,15 @@ scrub_item_init_ag(struct scrub_item *sri, xfs_agnumber_t agno)
sri->sri_gen = -1U;
}
+static inline void
+scrub_item_init_rtgroup(struct scrub_item *sri, xfs_rgnumber_t rgno)
+{
+ memset(sri, 0, sizeof(*sri));
+ sri->sri_agno = rgno;
+ sri->sri_ino = -1ULL;
+ sri->sri_gen = -1U;
+}
+
static inline void
scrub_item_init_fs(struct scrub_item *sri)
{