]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - scrub/fscounters.c
libfrog: fix workqueue error communication problems
[thirdparty/xfsprogs-dev.git] / scrub / fscounters.c
index f18d0e1992eb9e86b0c09a76a222ae04084d3129..669c5ab0cf09f70e8e459371b1ffe6ebabeed6b2 100644 (file)
 #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
@@ -34,37 +35,35 @@ struct xfs_count_inodes {
  * 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;
        }
 
@@ -82,8 +81,6 @@ xfs_count_ag_inodes(
        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"),
@@ -91,11 +88,7 @@ xfs_count_ag_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;
 }
@@ -122,15 +115,14 @@ xfs_count_all_inodes(
                        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;
                }
        }