From: Dave Chinner <david@fromorbit.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: sandeen@sandeen.net, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 3/6] misc: convert XFS_IOC_FSBULKSTAT to XFS_IOC_BULKSTAT
Date: Fri, 13 Sep 2019 10:54:26 +1000 [thread overview]
Message-ID: <20190913005426.GV16973@dread.disaster.area> (raw)
In-Reply-To: <156774091553.2643497.13127754211857633238.stgit@magnolia>
On Thu, Sep 05, 2019 at 08:35:15PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
>
> Convert the v1 calls to v5 calls.
>
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
> fsr/xfs_fsr.c | 45 ++++++--
> io/open.c | 17 ++-
> libfrog/bulkstat.c | 290 +++++++++++++++++++++++++++++++++++++++++++++++++---
> libfrog/bulkstat.h | 10 +-
> libfrog/fsgeom.h | 9 ++
> quota/quot.c | 29 ++---
> scrub/inodes.c | 45 +++++---
> scrub/inodes.h | 2
> scrub/phase3.c | 6 +
> scrub/phase5.c | 8 +
> scrub/phase6.c | 2
> scrub/unicrash.c | 6 +
> scrub/unicrash.h | 4 -
> spaceman/health.c | 28 +++--
> 14 files changed, 411 insertions(+), 90 deletions(-)
>
>
> diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
> index a53eb924..cc3cc93a 100644
> --- a/fsr/xfs_fsr.c
> +++ b/fsr/xfs_fsr.c
> @@ -466,6 +466,17 @@ fsrallfs(char *mtab, int howlong, char *leftofffile)
> ptr = strchr(ptr, ' ');
> if (ptr) {
> startino = strtoull(++ptr, NULL, 10);
> + /*
> + * NOTE: The inode number read in from
> + * the leftoff file is the last inode
> + * to have been fsr'd. Since the new
> + * xfrog_bulkstat function wants to be
> + * passed the first inode that we want
> + * to examine, increment the value that
> + * we read in. The debug message below
> + * prints the lastoff value.
> + */
> + startino++;
> }
> }
> if (startpass < 0)
> @@ -484,7 +495,7 @@ fsrallfs(char *mtab, int howlong, char *leftofffile)
>
> if (vflag) {
> fsrprintf(_("START: pass=%d ino=%llu %s %s\n"),
> - fs->npass, (unsigned long long)startino,
> + fs->npass, (unsigned long long)startino - 1,
> fs->dev, fs->mnt);
> }
This could probably go in a spearate patch....
> @@ -724,7 +724,6 @@ inode_f(
> char **argv)
> {
> struct xfs_bstat bstat;
> - uint32_t count = 0;
> uint64_t result_ino = 0;
> uint64_t userino = NULLFSINO;
> char *p;
> @@ -775,21 +774,31 @@ inode_f(
> }
> } else if (ret_next) {
> struct xfs_fd xfd = XFS_FD_INIT(file->fd);
> + struct xfs_bulkstat_req *breq;
> +
> + breq = xfrog_bulkstat_alloc_req(1, userino + 1);
> + if (!breq) {
> + perror("alloc bulkstat");
> + exitcode = 1;
> + return 0;
> + }
>
> /* get next inode */
> - ret = xfrog_bulkstat(&xfd, &userino, 1, &bstat, &count);
Why the "+ 1" on userino setup for the new interface?
> @@ -29,29 +42,278 @@ xfrog_bulkstat_single(
> return 0;
> }
>
> -/* Bulkstat a bunch of inodes. Returns zero or a positive error code. */
> -int
> -xfrog_bulkstat(
> +/*
> + * Set up emulation of a v5 bulk request ioctl with a v1 bulk request ioctl.
> + * Returns 0 if the emulation should proceed; ECANCELED if there are no
> + * records; or a positive error code.
> + */
> +static int
> +xfrog_bulk_req_setup(
> struct xfs_fd *xfd,
> - uint64_t *lastino,
> - uint32_t icount,
> - struct xfs_bstat *ubuffer,
> - uint32_t *ocount)
> + struct xfs_bulk_ireq *hdr,
> + struct xfs_fsop_bulkreq *bulkreq,
> + size_t rec_size)
> +{
> + void *buf;
> +
> + if (hdr->flags & XFS_BULK_IREQ_AGNO) {
> + uint32_t agno = cvt_ino_to_agno(xfd, hdr->ino);
> +
> + if (hdr->ino == 0)
> + hdr->ino = cvt_agino_to_ino(xfd, hdr->agno, 0);
> + else if (agno < hdr->agno)
> + return EINVAL;
> + else if (agno > hdr->agno)
> + goto no_results;
> + }
> +
> + if (cvt_ino_to_agno(xfd, hdr->ino) > xfd->fsgeom.agcount)
> + goto no_results;
> +
> + buf = malloc(hdr->icount * rec_size);
> + if (!buf)
> + return errno;
> +
> + if (hdr->ino)
> + hdr->ino--;
This goes with my last question: why?
> + bulkreq->lastip = (__u64 *)&hdr->ino,
> + bulkreq->icount = hdr->icount,
> + bulkreq->ocount = (__s32 *)&hdr->ocount,
> + bulkreq->ubuffer = buf;
> + return 0;
> +
> +no_results:
> + hdr->ocount = 0;
> + return ECANCELED;
We should be returning negative errors for everything.
> +}
> +
> +/*
> + * Convert records and free resources used to do a v1 emulation of v5 bulk
> + * request.
> + */
> +static int
> +xfrog_bulk_req_teardown(
What's "teardown" got to do with converting results to a v1 format?
Indeed, why is there even emulation of v1 calls in the first place?
why don't callers that need v1 format just use the existing v1
ioctls directly?
>
> +/* Bulkstat a bunch of inodes using the v1 interface. */
> +static int
> +xfrog_bulkstat1(
> + struct xfs_fd *xfd,
> + struct xfs_bulkstat_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_setup(xfd, &req->hdr, &bulkreq,
> + sizeof(struct xfs_bstat));
> + if (error == ECANCELED)
> + goto out_teardown;
> + if (error)
> + return error;
> +
> + error = ioctl(xfd->fd, XFS_IOC_FSBULKSTAT, &bulkreq);
> + if (error)
> + error = errno;
negative errors, please.
> +
> +out_teardown:
> + return xfrog_bulk_req_teardown(xfd, &req->hdr, &bulkreq,
> + sizeof(struct xfs_bstat), xfrog_bstat_ino,
> + &req->bulkstat, sizeof(struct xfs_bulkstat),
> + xfrog_bstat_cvt, 1, error);
> +}
What conversion is necessary here given we've done a v1 format
bulkstat?
> +/* Bulkstat a bunch of inodes. Returns zero or a positive error code. */
> +int
> +xfrog_bulkstat(
> + struct xfs_fd *xfd,
> + struct xfs_bulkstat_req *req)
> +{
> + int error;
> +
> + if (xfd->flags & XFROG_FLAG_BULKSTAT_FORCE_V1)
> + goto try_v1;
> +
> + error = xfrog_bulkstat5(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_bulkstat1(xfd, req);
> +}
Oh, wait, "v1 emulation" is supposed to mean "use a v1 call to
return v5 format structures"? That's emulation of the _v5_ ioctl,
which kinda says to me there's some naming problems here...
> +/* Convert bulkstat (v5) to bstat (v1). */
> +void
> +xfrog_bulkstat_to_bstat(
> + struct xfs_fd *xfd,
> + struct xfs_bstat *bs1,
> + const struct xfs_bulkstat *bstat)
Which I read as "convert bulkstat to bulkstat" and it doesn't tell
me what is actually going on. xfrog_bulkstat_v5_to_v1() indicates
what format conversion is actually taking place...
and um, naming the v5 field bstat, and the struct xfs_bstat field
bs1 is entirely confusing.
void
xfrog_bulkstat_v5_to_v1(
struct xfs_fd *xfd
const struct xfs_bulkstat *from,
struct xfs_bstat *to)
{
to->bs_ino = from->bs_ino;
....
> +{
> + bs1->bs_ino = bstat->bs_ino;
> + bs1->bs_mode = bstat->bs_mode;
> + bs1->bs_nlink = bstat->bs_nlink;
> + bs1->bs_uid = bstat->bs_uid;
> + bs1->bs_gid = bstat->bs_gid;
> + bs1->bs_rdev = bstat->bs_rdev;
> + bs1->bs_blksize = bstat->bs_blksize;
> + bs1->bs_size = bstat->bs_size;
> + bs1->bs_atime.tv_sec = bstat->bs_atime;
> + bs1->bs_mtime.tv_sec = bstat->bs_mtime;
> + bs1->bs_ctime.tv_sec = bstat->bs_ctime;
What about 32 bit overflows here?
> +/* Convert bstat (v1) to bulkstat (v5). */
> +void
> +xfrog_bstat_to_bulkstat(
> + struct xfs_fd *xfd,
> + struct xfs_bulkstat *bstat,
> + const struct xfs_bstat *bs1)
> +{
same comments about names here.
>
> +/* Only use v1 bulkstat/inumbers ioctls. */
> +#define XFROG_FLAG_BULKSTAT_FORCE_V1 (1 << 0)
> +
> +/* Only use v5 bulkstat/inumbers ioctls. */
> +#define XFROG_FLAG_BULKSTAT_FORCE_V5 (1 << 1)
These don't actually define what format the results are presented
in. What happens if the user wants v1 format structures but wants
the V5 ioctl to be used?
> --- a/scrub/inodes.c
> +++ b/scrub/inodes.c
> @@ -50,13 +50,15 @@ static void
> xfs_iterate_inodes_range_check(
> struct scrub_ctx *ctx,
> struct xfs_inogrp *inogrp,
> - struct xfs_bstat *bstat)
> + struct xfs_bulkstat *bstat)
> {
> - struct xfs_bstat *bs;
> + struct xfs_bulkstat *bs;
> int i;
> int error;
>
> for (i = 0, bs = bstat; i < XFS_INODES_PER_CHUNK; i++) {
> + struct xfs_bstat bs1;
> +
> if (!(inogrp->xi_allocmask & (1ULL << i)))
> continue;
> if (bs->bs_ino == inogrp->xi_startino + i) {
> @@ -66,11 +68,13 @@ xfs_iterate_inodes_range_check(
>
> /* Load the one inode. */
> error = xfrog_bulkstat_single(&ctx->mnt,
> - inogrp->xi_startino + i, bs);
> - if (error || bs->bs_ino != inogrp->xi_startino + i) {
> - memset(bs, 0, sizeof(struct xfs_bstat));
> + inogrp->xi_startino + i, &bs1);
> + if (error || bs1.bs_ino != inogrp->xi_startino + i) {
> + memset(bs, 0, sizeof(struct xfs_bulkstat));
> bs->bs_ino = inogrp->xi_startino + i;
> bs->bs_blksize = ctx->mnt_sv.f_frsize;
> + } else {
> + xfrog_bstat_to_bulkstat(&ctx->mnt, bs, &bs1);
I'm confused - why is xfrog_bulkstat_single() returning a v1 format
structure here and not using v5 format for everything?
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
next prev parent reply other threads:[~2019-09-13 0:54 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-06 3:34 [PATCH 0/6] xfsprogs: port utilities to bulkstat v5 Darrick J. Wong
2019-09-06 3:34 ` [PATCH 1/6] man: add documentation for v5 bulkstat ioctl Darrick J. Wong
2019-09-06 3:35 ` [PATCH 2/6] man: add documentation for v5 inumbers ioctl Darrick J. Wong
2019-09-06 3:35 ` [PATCH 3/6] misc: convert XFS_IOC_FSBULKSTAT to XFS_IOC_BULKSTAT Darrick J. Wong
2019-09-13 0:54 ` Dave Chinner [this message]
2019-09-16 21:58 ` Darrick J. Wong
2019-09-06 3:35 ` [PATCH 4/6] misc: convert to v5 bulkstat_single call Darrick J. Wong
2019-09-13 1:02 ` Dave Chinner
2019-09-16 22:02 ` Darrick J. Wong
2019-09-06 3:35 ` [PATCH 5/6] misc: convert from XFS_IOC_FSINUMBERS to XFS_IOC_INUMBERS Darrick J. Wong
2019-09-13 1:10 ` Dave Chinner
2019-09-16 22:05 ` Darrick J. Wong
2019-09-06 3:35 ` [PATCH 6/6] libxfs: revert FSGEOMETRY v5 -> v4 hack Darrick J. Wong
2019-09-10 6:46 ` Christoph Hellwig
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=20190913005426.GV16973@dread.disaster.area \
--to=david@fromorbit.com \
--cc=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