From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: sandeen@sandeen.net
Cc: linux-xfs@vger.kernel.org
Subject: [PATCH v2 4/4] misc: convert from XFS_IOC_FSINUMBERS to XFS_IOC_INUMBERS
Date: Fri, 27 Sep 2019 13:15:15 -0700 [thread overview]
Message-ID: <20190927201515.GR9916@magnolia> (raw)
In-Reply-To: <156944717162.297379.1042436133617221738.stgit@magnolia>
From: Darrick J. Wong <darrick.wong@oracle.com>
Convert all programs to use the v5 inumbers ioctl.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
io/imap.c | 26 +++++-----
io/open.c | 29 +++++++----
libfrog/bulkstat.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++------
libfrog/bulkstat.h | 10 +++-
scrub/fscounters.c | 21 +++++---
scrub/inodes.c | 46 ++++++++++--------
6 files changed, 194 insertions(+), 70 deletions(-)
diff --git a/io/imap.c b/io/imap.c
index 472c1fda..fa69676e 100644
--- a/io/imap.c
+++ b/io/imap.c
@@ -17,9 +17,7 @@ static int
imap_f(int argc, char **argv)
{
struct xfs_fd xfd = XFS_FD_INIT(file->fd);
- struct xfs_inogrp *t;
- uint64_t last = 0;
- uint32_t count;
+ struct xfs_inumbers_req *ireq;
uint32_t nent;
int i;
int error;
@@ -29,17 +27,19 @@ imap_f(int argc, char **argv)
else
nent = atoi(argv[1]);
- t = malloc(nent * sizeof(*t));
- if (!t)
+ ireq = xfrog_inumbers_alloc_req(nent, 0);
+ if (!ireq) {
+ perror("alloc req");
return 0;
+ }
- while ((error = xfrog_inumbers(&xfd, &last, nent, t, &count)) == 0 &&
- count > 0) {
- for (i = 0; i < count; i++) {
- printf(_("ino %10llu count %2d mask %016llx\n"),
- (unsigned long long)t[i].xi_startino,
- t[i].xi_alloccount,
- (unsigned long long)t[i].xi_allocmask);
+ while ((error = xfrog_inumbers(&xfd, ireq)) == 0 &&
+ ireq->hdr.ocount > 0) {
+ for (i = 0; i < ireq->hdr.ocount; i++) {
+ printf(_("ino %10"PRIu64" count %2d mask %016"PRIx64"\n"),
+ ireq->inumbers[i].xi_startino,
+ ireq->inumbers[i].xi_alloccount,
+ ireq->inumbers[i].xi_allocmask);
}
}
@@ -48,7 +48,7 @@ imap_f(int argc, char **argv)
perror("xfsctl(XFS_IOC_FSINUMBERS)");
exitcode = 1;
}
- free(t);
+ free(ireq);
return 0;
}
diff --git a/io/open.c b/io/open.c
index e0e7fb3e..fa9ca01a 100644
--- a/io/open.c
+++ b/io/open.c
@@ -681,39 +681,44 @@ static __u64
get_last_inode(void)
{
struct xfs_fd xfd = XFS_FD_INIT(file->fd);
- uint64_t lastip = 0;
+ struct xfs_inumbers_req *ireq;
uint32_t lastgrp = 0;
- uint32_t ocount = 0;
- __u64 last_ino;
- struct xfs_inogrp igroup[IGROUP_NR];
+ __u64 last_ino = 0;
+
+ ireq = xfrog_inumbers_alloc_req(IGROUP_NR, 0);
+ if (!ireq) {
+ perror("alloc req");
+ return 0;
+ }
for (;;) {
int ret;
- ret = xfrog_inumbers(&xfd, &lastip, IGROUP_NR, igroup,
- &ocount);
+ ret = xfrog_inumbers(&xfd, ireq);
if (ret) {
errno = ret;
perror("XFS_IOC_FSINUMBERS");
- return 0;
+ goto out;
}
/* Did we reach the last inode? */
- if (ocount == 0)
+ if (ireq->hdr.ocount == 0)
break;
/* last inode in igroup table */
- lastgrp = ocount;
+ lastgrp = ireq->hdr.ocount;
}
if (lastgrp == 0)
- return 0;
+ goto out;
lastgrp--;
/* The last inode number in use */
- last_ino = igroup[lastgrp].xi_startino +
- libxfs_highbit64(igroup[lastgrp].xi_allocmask);
+ last_ino = ireq->inumbers[lastgrp].xi_startino +
+ libxfs_highbit64(ireq->inumbers[lastgrp].xi_allocmask);
+out:
+ free(ireq);
return last_ino;
}
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
index 300963f1..85594e5e 100644
--- a/libfrog/bulkstat.c
+++ b/libfrog/bulkstat.c
@@ -435,6 +435,86 @@ xfrog_bulkstat_alloc_req(
return breq;
}
+/* Convert a inumbers data from v5 format to v1 format. */
+void
+xfrog_inumbers_v5_to_v1(
+ struct xfs_inogrp *ig1,
+ const struct xfs_inumbers *ig5)
+{
+ ig1->xi_startino = ig5->xi_startino;
+ ig1->xi_alloccount = ig5->xi_alloccount;
+ ig1->xi_allocmask = ig5->xi_allocmask;
+}
+
+/* Convert a inumbers data from v1 format to v5 format. */
+void
+xfrog_inumbers_v1_to_v5(
+ struct xfs_inumbers *ig5,
+ const struct xfs_inogrp *ig1)
+{
+ memset(ig5, 0, sizeof(*ig5));
+ ig5->xi_version = XFS_INUMBERS_VERSION_V1;
+
+ ig5->xi_startino = ig1->xi_startino;
+ ig5->xi_alloccount = ig1->xi_alloccount;
+ ig5->xi_allocmask = ig1->xi_allocmask;
+}
+
+static uint64_t xfrog_inum_ino(void *v1_rec)
+{
+ return ((struct xfs_inogrp *)v1_rec)->xi_startino;
+}
+
+static void xfrog_inum_cvt(struct xfs_fd *xfd, void *v5, void *v1)
+{
+ xfrog_inumbers_v1_to_v5(v5, v1);
+}
+
+/* Query inode allocation bitmask information using v5 ioctl. */
+static int
+xfrog_inumbers5(
+ struct xfs_fd *xfd,
+ struct xfs_inumbers_req *req)
+{
+ int ret;
+
+ ret = ioctl(xfd->fd, XFS_IOC_INUMBERS, req);
+ if (ret)
+ return errno;
+ return 0;
+}
+
+/* Query inode allocation bitmask information using v1 ioctl. */
+static int
+xfrog_inumbers1(
+ struct xfs_fd *xfd,
+ struct xfs_inumbers_req *req)
+{
+ struct xfs_fsop_bulkreq bulkreq = { 0 };
+ int error;
+
+ error = xfrog_bulkstat_prep_v1_emulation(xfd);
+ if (error)
+ return error;
+
+ error = xfrog_bulk_req_v1_setup(xfd, &req->hdr, &bulkreq,
+ sizeof(struct xfs_inogrp));
+ if (error == ECANCELED)
+ goto out_teardown;
+ if (error)
+ return error;
+
+ error = ioctl(xfd->fd, XFS_IOC_FSINUMBERS, &bulkreq);
+ if (error)
+ error = errno;
+
+out_teardown:
+ return xfrog_bulk_req_v1_cleanup(xfd, &req->hdr, &bulkreq,
+ sizeof(struct xfs_inogrp), xfrog_inum_ino,
+ &req->inumbers, sizeof(struct xfs_inumbers),
+ xfrog_inum_cvt, 64, error);
+}
+
/*
* Query inode allocation bitmask information. Returns zero or a positive
* error code.
@@ -442,21 +522,43 @@ xfrog_bulkstat_alloc_req(
int
xfrog_inumbers(
struct xfs_fd *xfd,
- uint64_t *lastino,
- uint32_t icount,
- struct xfs_inogrp *ubuffer,
- uint32_t *ocount)
+ struct xfs_inumbers_req *req)
{
- struct xfs_fsop_bulkreq bulkreq = {
- .lastip = (__u64 *)lastino,
- .icount = icount,
- .ubuffer = ubuffer,
- .ocount = (__s32 *)ocount,
- };
- int ret;
+ int error;
- ret = ioctl(xfd->fd, XFS_IOC_FSINUMBERS, &bulkreq);
- if (ret)
- return errno;
- return 0;
+ if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
+ goto try_v1;
+
+ error = xfrog_inumbers5(xfd, req);
+ if (error == 0 || (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V5))
+ return error;
+
+ /* If the v5 ioctl wasn't found, we punt to v1. */
+ switch (error) {
+ case EOPNOTSUPP:
+ case ENOTTY:
+ xfd->flags |= XFROG_FLAG_BULKSTAT_FORCE_V1;
+ break;
+ }
+
+try_v1:
+ return xfrog_inumbers1(xfd, req);
+}
+
+/* Allocate a inumbers request. On error returns NULL and sets errno. */
+struct xfs_inumbers_req *
+xfrog_inumbers_alloc_req(
+ uint32_t nr,
+ uint64_t startino)
+{
+ struct xfs_inumbers_req *ireq;
+
+ ireq = calloc(1, XFS_INUMBERS_REQ_SIZE(nr));
+ if (!ireq)
+ return NULL;
+
+ ireq->hdr.icount = nr;
+ ireq->hdr.ino = startino;
+
+ return ireq;
}
diff --git a/libfrog/bulkstat.h b/libfrog/bulkstat.h
index bbbc69a2..a085da3d 100644
--- a/libfrog/bulkstat.h
+++ b/libfrog/bulkstat.h
@@ -20,7 +20,13 @@ void xfrog_bulkstat_v1_to_v5(struct xfs_fd *xfd, struct xfs_bulkstat *bstat,
const struct xfs_bstat *bs1);
struct xfs_inogrp;
-int xfrog_inumbers(struct xfs_fd *xfd, uint64_t *lastino, uint32_t icount,
- struct xfs_inogrp *ubuffer, uint32_t *ocount);
+int xfrog_inumbers(struct xfs_fd *xfd, struct xfs_inumbers_req *req);
+
+struct xfs_inumbers_req *xfrog_inumbers_alloc_req(uint32_t nr,
+ uint64_t startino);
+void xfrog_inumbers_v5_to_v1(struct xfs_inogrp *ig1,
+ const struct xfs_inumbers *ig);
+void xfrog_inumbers_v1_to_v5(struct xfs_inumbers *ig,
+ const struct xfs_inogrp *ig1);
#endif /* __LIBFROG_BULKSTAT_H__ */
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index 8e4b3467..2fdf658a 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -42,23 +42,28 @@ xfs_count_inodes_range(
uint64_t last_ino,
uint64_t *count)
{
- struct xfs_inogrp inogrp;
- uint64_t igrp_ino;
+ struct xfs_inumbers_req *ireq;
uint64_t nr = 0;
- uint32_t igrplen = 0;
int error;
ASSERT(!(first_ino & (XFS_INODES_PER_CHUNK - 1)));
ASSERT((last_ino & (XFS_INODES_PER_CHUNK - 1)));
- igrp_ino = first_ino;
- while (!(error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
- &igrplen))) {
- if (igrplen == 0 || inogrp.xi_startino >= last_ino)
+ ireq = xfrog_inumbers_alloc_req(1, first_ino);
+ if (!ireq) {
+ str_info(ctx, descr, _("Insufficient memory; giving up."));
+ return false;
+ }
+
+ while (!(error = xfrog_inumbers(&ctx->mnt, ireq))) {
+ if (ireq->hdr.ocount == 0 ||
+ ireq->inumbers[0].xi_startino >= last_ino)
break;
- nr += inogrp.xi_alloccount;
+ nr += ireq->inumbers[0].xi_alloccount;
}
+ free(ireq);
+
if (error) {
str_liberror(ctx, error, descr);
return false;
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 4c95f635..c50f2de6 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -49,7 +49,7 @@
static void
xfs_iterate_inodes_range_check(
struct scrub_ctx *ctx,
- struct xfs_inogrp *inogrp,
+ struct xfs_inumbers *inumbers,
struct xfs_bulkstat *bstat)
{
struct xfs_bulkstat *bs;
@@ -57,19 +57,19 @@ xfs_iterate_inodes_range_check(
int error;
for (i = 0, bs = bstat; i < XFS_INODES_PER_CHUNK; i++) {
- if (!(inogrp->xi_allocmask & (1ULL << i)))
+ if (!(inumbers->xi_allocmask & (1ULL << i)))
continue;
- if (bs->bs_ino == inogrp->xi_startino + i) {
+ if (bs->bs_ino == inumbers->xi_startino + i) {
bs++;
continue;
}
/* Load the one inode. */
error = xfrog_bulkstat_single(&ctx->mnt,
- inogrp->xi_startino + i, 0, bs);
- if (error || bs->bs_ino != inogrp->xi_startino + i) {
+ inumbers->xi_startino + i, 0, bs);
+ if (error || bs->bs_ino != inumbers->xi_startino + i) {
memset(bs, 0, sizeof(struct xfs_bulkstat));
- bs->bs_ino = inogrp->xi_startino + i;
+ bs->bs_ino = inumbers->xi_startino + i;
bs->bs_blksize = ctx->mnt_sv.f_frsize;
}
bs++;
@@ -92,12 +92,11 @@ xfs_iterate_inodes_range(
void *arg)
{
struct xfs_handle handle;
- struct xfs_inogrp inogrp;
+ struct xfs_inumbers_req *ireq;
struct xfs_bulkstat_req *breq;
char idescr[DESCR_BUFSZ];
struct xfs_bulkstat *bs;
- uint64_t igrp_ino;
- uint32_t igrplen = 0;
+ struct xfs_inumbers *inumbers;
bool moveon = true;
int i;
int error;
@@ -114,19 +113,26 @@ xfs_iterate_inodes_range(
return false;
}
+ ireq = xfrog_inumbers_alloc_req(1, first_ino);
+ if (!ireq) {
+ str_info(ctx, descr, _("Insufficient memory; giving up."));
+ free(breq);
+ return false;
+ }
+ inumbers = &ireq->inumbers[0];
+
/* Find the inode chunk & alloc mask */
- igrp_ino = first_ino;
- error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp, &igrplen);
- while (!error && igrplen) {
+ error = xfrog_inumbers(&ctx->mnt, ireq);
+ while (!error && ireq->hdr.ocount > 0) {
/*
* We can have totally empty inode chunks on filesystems where
* there are more than 64 inodes per block. Skip these.
*/
- if (inogrp.xi_alloccount == 0)
+ if (inumbers->xi_alloccount == 0)
goto igrp_retry;
- breq->hdr.ino = inogrp.xi_startino;
- breq->hdr.icount = inogrp.xi_alloccount;
+ breq->hdr.ino = inumbers->xi_startino;
+ breq->hdr.icount = inumbers->xi_alloccount;
error = xfrog_bulkstat(&ctx->mnt, breq);
if (error) {
char errbuf[DESCR_BUFSZ];
@@ -135,11 +141,11 @@ xfs_iterate_inodes_range(
errbuf, DESCR_BUFSZ));
}
- xfs_iterate_inodes_range_check(ctx, &inogrp, breq->bulkstat);
+ xfs_iterate_inodes_range_check(ctx, inumbers, breq->bulkstat);
/* Iterate all the inodes. */
for (i = 0, bs = breq->bulkstat;
- i < inogrp.xi_alloccount;
+ i < inumbers->xi_alloccount;
i++, bs++) {
if (bs->bs_ino > last_ino)
goto out;
@@ -153,7 +159,7 @@ xfs_iterate_inodes_range(
case ESTALE:
stale_count++;
if (stale_count < 30) {
- igrp_ino = inogrp.xi_startino;
+ ireq->hdr.ino = inumbers->xi_startino;
goto igrp_retry;
}
snprintf(idescr, DESCR_BUFSZ, "inode %"PRIu64,
@@ -177,8 +183,7 @@ _("Changed too many times during scan; giving up."));
stale_count = 0;
igrp_retry:
- error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
- &igrplen);
+ error = xfrog_inumbers(&ctx->mnt, ireq);
}
err:
@@ -187,6 +192,7 @@ _("Changed too many times during scan; giving up."));
moveon = false;
}
out:
+ free(ireq);
free(breq);
return moveon;
}
next prev parent reply other threads:[~2019-09-27 20:15 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-25 21:32 [PATCH 0/4] xfsprogs: port utilities to bulkstat v5 Darrick J. Wong
2019-09-25 21:32 ` [PATCH 1/4] man: add documentation for v5 bulkstat ioctl Darrick J. Wong
2019-09-26 18:18 ` Eric Sandeen
2019-09-26 19:01 ` Darrick J. Wong
2019-09-26 19:10 ` [PATCH v2 " Darrick J. Wong
2019-09-26 19:11 ` Eric Sandeen
2019-09-27 3:44 ` [PATCH v3 " Darrick J. Wong
2019-09-27 17:23 ` Eric Sandeen
2019-09-25 21:32 ` [PATCH 2/4] man: add documentation for v5 inumbers ioctl Darrick J. Wong
2019-09-26 18:36 ` Eric Sandeen
2019-09-26 18:49 ` Eric Sandeen
2019-09-26 19:10 ` [PATCH v2 " Darrick J. Wong
2019-09-27 3:44 ` [PATCH v3 " Darrick J. Wong
2019-09-27 17:25 ` Eric Sandeen
2019-09-25 21:32 ` [PATCH 3/4] misc: convert xfrog_bulkstat functions to have v5 semantics Darrick J. Wong
2019-09-26 21:01 ` Eric Sandeen
2019-09-27 3:50 ` Darrick J. Wong
2019-09-27 20:14 ` [PATCH v2 " Darrick J. Wong
2019-09-27 20:29 ` Eric Sandeen
2019-09-25 21:32 ` [PATCH 4/4] misc: convert from XFS_IOC_FSINUMBERS to XFS_IOC_INUMBERS Darrick J. Wong
2019-09-26 21:48 ` Eric Sandeen
2019-09-27 3:54 ` Darrick J. Wong
2019-09-27 20:15 ` Darrick J. Wong [this message]
2019-09-27 20:30 ` [PATCH v2 " Eric Sandeen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190927201515.GR9916@magnolia \
--to=darrick.wong@oracle.com \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@sandeen.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).