#include "platform_defs.h"
#include "xfs_arch.h"
#include "xfs_format.h"
-#include "path.h"
-#include "workqueue.h"
+#include "libfrog/paths.h"
+#include "libfrog/workqueue.h"
#include "xfs_scrub.h"
#include "common.h"
#include "fscounters.h"
+#include "libfrog/bulkstat.h"
/*
* Filesystem counter collection routines. We can count the number of
* exist in the filesystem, assuming we've already scrubbed that.
*/
static bool
-xfs_count_inodes_range(
+xfs_count_inodes_ag(
struct scrub_ctx *ctx,
const char *descr,
- uint64_t first_ino,
- uint64_t last_ino,
+ uint32_t agno,
uint64_t *count)
{
- struct xfs_fsop_bulkreq igrpreq = {NULL};
- struct xfs_inogrp inogrp;
- __u64 igrp_ino;
+ struct xfs_inumbers_req *ireq;
uint64_t nr = 0;
- __s32 igrplen = 0;
+ unsigned int i;
int error;
- ASSERT(!(first_ino & (XFS_INODES_PER_CHUNK - 1)));
- ASSERT((last_ino & (XFS_INODES_PER_CHUNK - 1)));
-
- igrpreq.lastip = &igrp_ino;
- igrpreq.icount = 1;
- igrpreq.ubuffer = &inogrp;
- igrpreq.ocount = &igrplen;
+ ireq = xfrog_inumbers_alloc_req(64, 0);
+ if (!ireq) {
+ str_info(ctx, descr, _("Insufficient memory; giving up."));
+ return false;
+ }
+ xfrog_inumbers_set_ag(ireq, agno);
- igrp_ino = first_ino;
- error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
- while (!error && igrplen && inogrp.xi_startino < last_ino) {
- nr += inogrp.xi_alloccount;
- error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
+ while (!(error = xfrog_inumbers(&ctx->mnt, ireq))) {
+ if (ireq->hdr.ocount == 0)
+ break;
+ for (i = 0; i < ireq->hdr.ocount; i++)
+ nr += ireq->inumbers[i].xi_alloccount;
}
+ free(ireq);
+
if (error) {
- str_errno(ctx, descr);
+ str_liberror(ctx, error, descr);
return false;
}
struct xfs_count_inodes *ci = arg;
struct scrub_ctx *ctx = (struct scrub_ctx *)wq->wq_ctx;
char descr[DESCR_BUFSZ];
- uint64_t ag_ino;
- uint64_t next_ag_ino;
bool moveon;
snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u inodes"),
minor(ctx->fsinfo.fs_datadev),
agno);
- ag_ino = (__u64)agno << (ctx->inopblog + ctx->agblklog);
- next_ag_ino = (__u64)(agno + 1) << (ctx->inopblog + ctx->agblklog);
-
- moveon = xfs_count_inodes_range(ctx, descr, ag_ino, next_ag_ino - 1,
- &ci->counters[agno]);
+ moveon = xfs_count_inodes_ag(ctx, descr, agno, &ci->counters[agno]);
if (!moveon)
ci->moveon = false;
}
scrub_nproc_workqueue(ctx));
if (ret) {
moveon = false;
- str_info(ctx, ctx->mntpoint, _("Could not create workqueue."));
+ str_liberror(ctx, ret, _("creating icount workqueue"));
goto out_free;
}
for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
ret = workqueue_add(&wq, xfs_count_ag_inodes, agno, ci);
if (ret) {
moveon = false;
- str_info(ctx, ctx->mntpoint,
-_("Could not queue AG %u icount work."), agno);
+ str_liberror(ctx, ret, _("queueing icount work"));
break;
}
}