struct media_verify_state {
struct ptvar *verify_schedules;
- struct read_verify_pool *rvp_data;
- struct read_verify_pool *rvp_log;
- struct read_verify_pool *rvp_realtime;
+ struct read_verify_pool *rvp[XFS_DEV_RT + 1];
+
struct bitmap *d_bad; /* bytes */
struct bitmap *r_bad; /* bytes */
struct bitmap *l_bad; /* bytes */
bool l_trunc:1;
};
-/* Find the fd for a given device identifier. */
-static struct read_verify_pool *
-dev_to_pool(
- struct scrub_ctx *ctx,
- struct media_verify_state *vs,
- dev_t dev)
+/* Return XFS device index from fsmap device. */
+static enum xfs_device
+from_fsmap_dev(
+ struct scrub_ctx *ctx,
+ dev_t dev)
{
if (ctx->mnt.fsgeom.rtstart) {
- if (dev == XFS_DEV_DATA)
- return vs->rvp_data;
- if (dev == XFS_DEV_LOG)
- return vs->rvp_log;
- if (dev == XFS_DEV_RT)
- return vs->rvp_realtime;
- } else {
- if (dev == ctx->fsinfo.fs_datadev)
- return vs->rvp_data;
- if (dev == ctx->fsinfo.fs_logdev)
- return vs->rvp_log;
- if (dev == ctx->fsinfo.fs_rtdev)
- return vs->rvp_realtime;
+ if (dev < XFS_DEV_DATA || dev > XFS_DEV_RT)
+ abort();
+ return dev;
}
+
+ if (dev == ctx->fsinfo.fs_datadev)
+ return XFS_DEV_DATA;
+ if (dev == ctx->fsinfo.fs_logdev)
+ return XFS_DEV_LOG;
+ if (dev == ctx->fsinfo.fs_rtdev)
+ return XFS_DEV_RT;
abort();
}
void *arg)
{
struct media_verify_state *vs = arg;
- struct read_verify_pool *rvp;
+ struct read_verify_pool *rvp =
+ vs->rvp[from_fsmap_dev(ctx, map->fmr_device)];
struct read_verify_schedule *rs;
bool scheduled;
int ret;
- rvp = dev_to_pool(ctx, vs, map->fmr_device);
-
dbg_printf("rmap dev %d:%d phys %"PRIu64" owner %"PRId64
" offset %"PRIu64" len %"PRIu64" flags 0x%x\n",
major(map->fmr_device), minor(map->fmr_device),
/* Wait for read/verify actions to finish, then return # bytes checked. */
static int
clean_pool(
- struct read_verify_pool *rvp,
- unsigned long long *bytes_checked)
+ struct media_verify_state *vs,
+ enum xfs_device dev,
+ unsigned long long *bytes_checked)
{
- uint64_t pool_checked;
- int ret;
+ struct read_verify_pool *rvp = vs->rvp[dev];
+ uint64_t pool_checked;
+ int ret;
if (!rvp)
return 0;
str_liberror(ctx, ret, _("setting bad block bitmap"));
}
+static inline int
+alloc_pool(
+ struct scrub_ctx *ctx,
+ struct media_verify_state *vs,
+ enum xfs_device dev)
+{
+ return read_verify_pool_alloc(ctx, dev, remember_ioerr, vs,
+ &vs->rvp[dev]);
+}
+
+static inline void
+free_pool(
+ struct media_verify_state *vs,
+ enum xfs_device dev)
+{
+ if (vs->rvp[dev]) {
+ read_verify_pool_abort(vs->rvp[dev]);
+ read_verify_pool_destroy(vs->rvp[dev]);
+ }
+}
+
/*
* Read verify all the file data blocks in a filesystem. Since XFS doesn't
* do data checksums, we trust that the underlying storage will pass back
goto out_rbad;
}
- ret = read_verify_pool_alloc(ctx, XFS_DEV_DATA, remember_ioerr, &vs,
- &vs.rvp_data);
+ ret = alloc_pool(ctx, &vs, XFS_DEV_DATA);
if (ret) {
str_liberror(ctx, ret, _("creating datadev media verifier"));
goto out_lbad;
}
if (ctx->fsinfo.fs_log) {
- ret = read_verify_pool_alloc(ctx, XFS_DEV_LOG, remember_ioerr,
- &vs, &vs.rvp_log);
+ ret = alloc_pool(ctx, &vs, XFS_DEV_LOG);
if (ret) {
str_liberror(ctx, ret,
_("creating logdev media verifier"));
}
}
if (ctx->fsinfo.fs_rt) {
- ret = read_verify_pool_alloc(ctx, XFS_DEV_RT, remember_ioerr,
- &vs, &vs.rvp_realtime);
+ ret = alloc_pool(ctx, &vs, XFS_DEV_RT);
if (ret) {
str_liberror(ctx, ret,
_("creating rtdev media verifier"));
ptvar_free(vs.verify_schedules);
vs.verify_schedules = NULL;
- ret = clean_pool(vs.rvp_data, &ctx->bytes_checked);
+ ret = clean_pool(&vs, XFS_DEV_DATA, &ctx->bytes_checked);
if (ret)
str_liberror(ctx, ret, _("flushing datadev verify pool"));
- ret2 = clean_pool(vs.rvp_log, &ctx->bytes_checked);
+ ret2 = clean_pool(&vs, XFS_DEV_LOG, &ctx->bytes_checked);
if (ret2)
str_liberror(ctx, ret2, _("flushing logdev verify pool"));
- ret3 = clean_pool(vs.rvp_realtime, &ctx->bytes_checked);
+ ret3 = clean_pool(&vs, XFS_DEV_RT, &ctx->bytes_checked);
if (ret3)
str_liberror(ctx, ret3, _("flushing rtdev verify pool"));
out_schedules:
ptvar_free(vs.verify_schedules);
out_rtpool:
- if (vs.rvp_realtime) {
- read_verify_pool_abort(vs.rvp_realtime);
- read_verify_pool_destroy(vs.rvp_realtime);
- }
+ free_pool(&vs, XFS_DEV_RT);
out_logpool:
- if (vs.rvp_log) {
- read_verify_pool_abort(vs.rvp_log);
- read_verify_pool_destroy(vs.rvp_log);
- }
+ free_pool(&vs, XFS_DEV_LOG);
out_datapool:
- read_verify_pool_abort(vs.rvp_data);
- read_verify_pool_destroy(vs.rvp_data);
+ free_pool(&vs, XFS_DEV_DATA);
out_lbad:
bitmap_free(&vs.l_bad);
out_rbad: