All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/12] xfsprogs-5.1: fix various problems
@ 2019-06-20 16:49 Darrick J. Wong
  2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
                   ` (11 more replies)
  0 siblings, 12 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:49 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

Hi all,

Latest respin of patches fixing various problems in xfsprogs.

The first two patches fix some problems in the number conversion code.

Patches 3-5 introduce a new structure for managing xfs runtime context.
For now this simply associates a file descriptor with reported xfs geometry
(and some computed values) that enable us to refactor per-ag calculations
out of xfs_scrub.  Later we'll use for things like graceful degradation
when xfsprogs supports bulkstat v5 but the kernel doesn't, and also doing
per-ag scanning operations.

Patches 6-8 refactor all utilities to use common libfrog functions to
retrieve the filesystem geometry, bulkstat, and inumbers.  The helpers
will make it easier for newer userspace to fall back to older versions
of ioctls.

Patch 9 strengthens mkfs's log alignment checking code.

Patch 10 fixes xfs_io repair command error reporting.

Patch 11 fixes libxfs-diff to handle files that are in libxfs/ in xfsprogs
but still in fs/xfs/ in the kernel.

Patch 12 adds a new "btheight" command to xfs_db so that we can calculate
the size of each level of a theoretical btree.

If you're going to start using this mess, you probably ought to just
pull from my git trees, which are linked below.

This is an extraordinary way to destroy everything.  Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=xfsprogs-5.1-fixes

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 01/12] libfrog: don't set negative errno in conversion functions
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
@ 2019-06-20 16:49 ` Darrick J. Wong
  2019-06-20 18:58   ` Eric Sandeen
  2019-06-25 11:02   ` Christoph Hellwig
  2019-06-20 16:49 ` [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll Darrick J. Wong
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:49 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Don't set errno to a negative value when we're converting integers.
That's a kernel thing; this is userspace.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libfrog/convert.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)


diff --git a/libfrog/convert.c b/libfrog/convert.c
index ed4cae7f..62397507 100644
--- a/libfrog/convert.c
+++ b/libfrog/convert.c
@@ -47,7 +47,7 @@ cvt_s64(
 		return i;
 
 	/* Not all the input was consumed, return error. */
-	errno = -ERANGE;
+	errno = ERANGE;
 	return INT64_MIN;
 }
 
@@ -68,7 +68,7 @@ cvt_s32(
 	if (errno)
 		return i;
 	if (i > INT32_MAX || i < INT32_MIN) {
-		errno = -ERANGE;
+		errno = ERANGE;
 		return INT32_MIN;
 	}
 	return i;
@@ -91,7 +91,7 @@ cvt_s16(
 	if (errno)
 		return i;
 	if (i > INT16_MAX || i < INT16_MIN) {
-		errno = -ERANGE;
+		errno = ERANGE;
 		return INT16_MIN;
 	}
 	return i;
@@ -123,7 +123,7 @@ cvt_u64(
 		return i;
 
 	/* Not all the input was consumed, return error. */
-	errno = -ERANGE;
+	errno = ERANGE;
 	return UINT64_MAX;
 }
 
@@ -144,7 +144,7 @@ cvt_u32(
 	if (errno)
 		return i;
 	if (i > UINT32_MAX) {
-		errno = -ERANGE;
+		errno = ERANGE;
 		return UINT32_MAX;
 	}
 	return i;
@@ -167,7 +167,7 @@ cvt_u16(
 	if (errno)
 		return i;
 	if (i > UINT16_MAX) {
-		errno = -ERANGE;
+		errno = ERANGE;
 		return UINT16_MAX;
 	}
 	return i;

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
  2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
@ 2019-06-20 16:49 ` Darrick J. Wong
  2019-06-20 19:08   ` Eric Sandeen
  2019-06-25 11:02   ` Christoph Hellwig
  2019-06-20 16:49 ` [PATCH 03/12] libfrog: refactor online geometry queries Darrick J. Wong
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:49 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

cvt_u64 converts a string to an unsigned 64-bit number, so it should use
strtoull, not strtoll because we don't want negative numbers here.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 libfrog/convert.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)


diff --git a/libfrog/convert.c b/libfrog/convert.c
index 62397507..8d4d4077 100644
--- a/libfrog/convert.c
+++ b/libfrog/convert.c
@@ -105,14 +105,14 @@ cvt_s16(
  */
 uint64_t
 cvt_u64(
-	char		*s,
-	int		base)
+	char			*s,
+	int			base)
 {
-	long long	i;
-	char		*sp;
+	unsigned long long	i;
+	char			*sp;
 
 	errno = 0;
-	i = strtoll(s, &sp, base);
+	i = strtoull(s, &sp, base);
 	/*
 	 * If the input would over or underflow, return the clamped
 	 * value and let the user check errno.  If we went all the

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 03/12] libfrog: refactor online geometry queries
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
  2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
  2019-06-20 16:49 ` [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll Darrick J. Wong
@ 2019-06-20 16:49 ` Darrick J. Wong
  2019-06-20 19:16   ` Eric Sandeen
  2019-06-25 14:28   ` Christoph Hellwig
  2019-06-20 16:49 ` [PATCH 04/12] libfrog: introduce xfrog context Darrick J. Wong
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:49 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Refactor all the open-coded XFS_IOC_FSGEOMETRY queries into a single
helper that we can use to standardize behaviors across mixed xfslibs
versions.  This is the prelude to introducing a new FSGEOMETRY version
in 5.2 and needing to fix the (relatively few) client programs.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 Makefile            |    1 +
 fsr/xfs_fsr.c       |   26 ++++----------------------
 growfs/xfs_growfs.c |   25 +++++++++----------------
 include/xfrog.h     |   22 ++++++++++++++++++++++
 io/bmap.c           |    3 ++-
 io/fsmap.c          |    3 ++-
 io/open.c           |    3 ++-
 io/stat.c           |    5 +++--
 libfrog/fsgeom.c    |   18 ++++++++++++++++++
 quota/free.c        |    6 +++---
 repair/xfs_repair.c |    5 +++--
 rtcp/Makefile       |    3 +++
 rtcp/xfs_rtcp.c     |    7 ++++---
 scrub/phase1.c      |    3 ++-
 spaceman/file.c     |    3 ++-
 spaceman/info.c     |   25 ++++++++-----------------
 16 files changed, 88 insertions(+), 70 deletions(-)
 create mode 100644 include/xfrog.h


diff --git a/Makefile b/Makefile
index 9204bed8..0edc2700 100644
--- a/Makefile
+++ b/Makefile
@@ -107,6 +107,7 @@ copy: libxlog
 mkfs: libxcmd
 spaceman: libxcmd
 scrub: libhandle libxcmd
+rtcp: libfrog
 
 ifeq ($(HAVE_BUILDDEFS), yes)
 include $(BUILDRULES)
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index fef6262c..0bfecf37 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -11,6 +11,7 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_attr_sf.h"
 #include "path.h"
+#include "xfrog.h"
 
 #include <fcntl.h>
 #include <errno.h>
@@ -83,9 +84,8 @@ int cmp(const void *, const void *);
 static void tmp_init(char *mnt);
 static char * tmp_next(char *mnt);
 static void tmp_close(char *mnt);
-int xfs_getgeom(int , xfs_fsop_geom_v1_t * );
 
-static xfs_fsop_geom_v1_t fsgeom;	/* geometry of active mounted system */
+static struct xfs_fsop_geom fsgeom;	/* geometry of active mounted system */
 
 #define NMOUNT 64
 static int numfs;
@@ -102,12 +102,6 @@ static int	nfrags = 0;	/* Debug option: Coerse into specific number
 				 * of extents */
 static int	openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT;
 
-static int
-xfs_fsgeometry(int fd, xfs_fsop_geom_v1_t *geom)
-{
-    return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, geom);
-}
-
 static int
 xfs_bulkstat_single(int fd, xfs_ino_t *lastip, xfs_bstat_t *ubuffer)
 {
@@ -630,7 +624,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
 		return -1;
 	}
 
-	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
+	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
 		fsrprintf(_("Skipping %s: could not get XFS geometry\n"),
 			  mntdir);
 		close(fsfd);
@@ -772,7 +766,7 @@ fsrfile(char *fname, xfs_ino_t ino)
 	}
 
 	/* Get the fs geometry */
-	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
+	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
 		fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
 		goto out;
 	}
@@ -1612,18 +1606,6 @@ getnextents(int fd)
 	return(nextents);
 }
 
-/*
- * Get the fs geometry
- */
-int
-xfs_getgeom(int fd, xfs_fsop_geom_v1_t * fsgeom)
-{
-	if (xfs_fsgeometry(fd, fsgeom) < 0) {
-		return -1;
-	}
-	return 0;
-}
-
 /*
  * Get xfs realtime space information
  */
diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c
index 20089d2b..28dd6d84 100644
--- a/growfs/xfs_growfs.c
+++ b/growfs/xfs_growfs.c
@@ -7,6 +7,7 @@
 #include "libxfs.h"
 #include "path.h"
 #include "fsgeom.h"
+#include "xfrog.h"
 
 static void
 usage(void)
@@ -165,22 +166,14 @@ main(int argc, char **argv)
 	}
 
 	/* get the current filesystem size & geometry */
-	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY, &geo) < 0) {
-		/*
-		 * OK, new xfsctl barfed - back off and try earlier version
-		 * as we're probably running an older kernel version.
-		 * Only field added in the v2 geometry xfsctl is "logsunit"
-		 * so we'll zero that out for later display (as zero).
-		 */
-		geo.logsunit = 0;
-		if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &geo) < 0) {
-			fprintf(stderr, _(
-				"%s: cannot determine geometry of filesystem"
-				" mounted at %s: %s\n"),
-				progname, fname, strerror(errno));
-			exit(1);
-		}
+	if (xfrog_geometry(ffd, &geo)) {
+		fprintf(stderr, _(
+			"%s: cannot determine geometry of filesystem"
+			" mounted at %s: %s\n"),
+			progname, fname, strerror(errno));
+		exit(1);
 	}
+
 	isint = geo.logstart > 0;
 
 	/*
@@ -359,7 +352,7 @@ main(int argc, char **argv)
 		}
 	}
 
-	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
+	if (xfrog_geometry(ffd, &ngeo)) {
 		fprintf(stderr, _("%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n"),
 			progname, strerror(errno));
 		exit(1);
diff --git a/include/xfrog.h b/include/xfrog.h
new file mode 100644
index 00000000..5420b47c
--- /dev/null
+++ b/include/xfrog.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc.
+ * All Rights Reserved.
+ */
+#ifndef __XFROG_H__
+#define __XFROG_H__
+
+/*
+ * XFS Filesystem Random Online Gluecode
+ * =====================================
+ *
+ * These support functions wrap the more complex xfs ioctls so that xfs
+ * utilities can take advantage of them without having to deal with graceful
+ * degradation in the face of new ioctls.  They will also provide higher level
+ * abstractions when possible.
+ */
+
+struct xfs_fsop_geom;
+int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
+
+#endif	/* __XFROG_H__ */
diff --git a/io/bmap.c b/io/bmap.c
index d408826a..5f0d12ca 100644
--- a/io/bmap.c
+++ b/io/bmap.c
@@ -9,6 +9,7 @@
 #include "input.h"
 #include "init.h"
 #include "io.h"
+#include "xfrog.h"
 
 static cmdinfo_t bmap_cmd;
 
@@ -105,7 +106,7 @@ bmap_f(
 		bmv_iflags &= ~(BMV_IF_PREALLOC|BMV_IF_NO_DMAPI_READ);
 
 	if (vflag) {
-		c = xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo);
+		c = xfrog_geometry(file->fd, &fsgeo);
 		if (c < 0) {
 			fprintf(stderr,
 				_("%s: can't get geometry [\"%s\"]: %s\n"),
diff --git a/io/fsmap.c b/io/fsmap.c
index 477c36fc..d3ff7dea 100644
--- a/io/fsmap.c
+++ b/io/fsmap.c
@@ -9,6 +9,7 @@
 #include "path.h"
 #include "io.h"
 #include "input.h"
+#include "xfrog.h"
 
 static cmdinfo_t	fsmap_cmd;
 static dev_t		xfs_data_dev;
@@ -447,7 +448,7 @@ fsmap_f(
 	}
 
 	if (vflag) {
-		c = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &fsgeo);
+		c = xfrog_geometry(file->fd, &fsgeo);
 		if (c < 0) {
 			fprintf(stderr,
 				_("%s: can't get geometry [\"%s\"]: %s\n"),
diff --git a/io/open.c b/io/open.c
index c7f5248a..997df119 100644
--- a/io/open.c
+++ b/io/open.c
@@ -9,6 +9,7 @@
 #include "init.h"
 #include "io.h"
 #include "libxfs.h"
+#include "xfrog.h"
 
 #ifndef __O_TMPFILE
 #if defined __alpha__
@@ -118,7 +119,7 @@ openfile(
 	if (flags & IO_PATH) {
 		/* Can't call ioctl() on O_PATH fds */
 		memset(geom, 0, sizeof(*geom));
-	} else if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
+	} else if (xfrog_geometry(fd, geom)) {
 		perror("XFS_IOC_FSGEOMETRY");
 		close(fd);
 		return -1;
diff --git a/io/stat.c b/io/stat.c
index 37c0b2e8..26b4eb68 100644
--- a/io/stat.c
+++ b/io/stat.c
@@ -12,6 +12,7 @@
 #include "io.h"
 #include "statx.h"
 #include "libxfs.h"
+#include "xfrog.h"
 
 #include <fcntl.h>
 
@@ -194,8 +195,8 @@ statfs_f(
 	}
 	if (file->flags & IO_FOREIGN)
 		return 0;
-	if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
-		perror("XFS_IOC_FSGEOMETRY_V1");
+	if (xfrog_geometry(file->fd, &fsgeo)) {
+		perror("XFS_IOC_FSGEOMETRY");
 	} else {
 		printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
 		printf(_("geom.agcount = %u\n"), fsgeo.agcount);
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 8879d161..a6dab3a8 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -4,6 +4,7 @@
  */
 #include "libxfs.h"
 #include "fsgeom.h"
+#include "xfrog.h"
 
 void
 xfs_report_geom(
@@ -67,3 +68,20 @@ xfs_report_geom(
 		geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks,
 			(unsigned long long)geo->rtextents);
 }
+
+/* Try to obtain the xfs geometry. */
+int
+xfrog_geometry(
+	int			fd,
+	struct xfs_fsop_geom	*fsgeo)
+{
+	int			ret;
+
+	memset(fsgeo, 0, sizeof(*fsgeo));
+
+	ret = ioctl(fd, XFS_IOC_FSGEOMETRY, fsgeo);
+	if (!ret)
+		return 0;
+
+	return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
+}
diff --git a/quota/free.c b/quota/free.c
index 1d13006e..f47001bf 100644
--- a/quota/free.c
+++ b/quota/free.c
@@ -8,6 +8,7 @@
 #include "command.h"
 #include "init.h"
 #include "quota.h"
+#include "xfrog.h"
 
 static cmdinfo_t free_cmd;
 
@@ -67,9 +68,8 @@ mount_free_space_data(
 	}
 
 	if (!(mount->fs_flags & FS_FOREIGN)) {
-		if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSGEOMETRY_V1,
-							&fsgeo)) < 0) {
-			perror("XFS_IOC_FSGEOMETRY_V1");
+		if (xfrog_geometry(fd, &fsgeo)) {
+			perror("XFS_IOC_FSGEOMETRY");
 			close(fd);
 			return 0;
 		}
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
index 9657503f..e6717d3c 100644
--- a/repair/xfs_repair.c
+++ b/repair/xfs_repair.c
@@ -22,6 +22,7 @@
 #include "dinode.h"
 #include "slab.h"
 #include "rmap.h"
+#include "xfrog.h"
 
 /*
  * option tables for getsubopt calls
@@ -636,11 +637,11 @@ check_fs_vs_host_sectsize(
 {
 	int	fd;
 	long	old_flags;
-	struct xfs_fsop_geom_v1 geom = { 0 };
+	struct xfs_fsop_geom	geom = { 0 };
 
 	fd = libxfs_device_to_fd(x.ddev);
 
-	if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) {
+	if (xfrog_geometry(fd, &geom)) {
 		do_log(_("Cannot get host filesystem geometry.\n"
 	"Repair may fail if there is a sector size mismatch between\n"
 	"the image and the host filesystem.\n"));
diff --git a/rtcp/Makefile b/rtcp/Makefile
index 808b5378..264b4f27 100644
--- a/rtcp/Makefile
+++ b/rtcp/Makefile
@@ -9,6 +9,9 @@ LTCOMMAND = xfs_rtcp
 CFILES = xfs_rtcp.c
 LLDFLAGS = -static
 
+LLDLIBS = $(LIBFROG)
+LTDEPENDENCIES = $(LIBFROG)
+
 default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
diff --git a/rtcp/xfs_rtcp.c b/rtcp/xfs_rtcp.c
index f928a86a..0b37ee89 100644
--- a/rtcp/xfs_rtcp.c
+++ b/rtcp/xfs_rtcp.c
@@ -5,6 +5,7 @@
  */
 
 #include "libxfs.h"
+#include "xfrog.h"
 
 int rtcp(char *, char *, int);
 int xfsrtextsize(char *path);
@@ -368,8 +369,8 @@ rtcp( char *source, char *target, int fextsize)
 int
 xfsrtextsize( char *path)
 {
-	int fd, rval, rtextsize;
-	xfs_fsop_geom_v1_t geo;
+	struct xfs_fsop_geom	geo;
+	int			fd, rval, rtextsize;
 
 	fd = open( path, O_RDONLY );
 	if ( fd < 0 ) {
@@ -377,7 +378,7 @@ xfsrtextsize( char *path)
 			progname, path, strerror(errno));
 		return -1;
 	}
-	rval = xfsctl( path, fd, XFS_IOC_FSGEOMETRY_V1, &geo );
+	rval = xfrog_geometry(fd, &geo);
 	close(fd);
 	if ( rval < 0 )
 		return -1;
diff --git a/scrub/phase1.c b/scrub/phase1.c
index 04a5f4a9..5ab2a4fe 100644
--- a/scrub/phase1.c
+++ b/scrub/phase1.c
@@ -26,6 +26,7 @@
 #include "disk.h"
 #include "scrub.h"
 #include "repair.h"
+#include "xfrog.h"
 
 /* Phase 1: Find filesystem geometry (and clean up after) */
 
@@ -129,7 +130,7 @@ _("Does not appear to be an XFS filesystem!"));
 	}
 
 	/* Retrieve XFS geometry. */
-	error = ioctl(ctx->mnt_fd, XFS_IOC_FSGEOMETRY, &ctx->geo);
+	error = xfrog_geometry(ctx->mnt_fd, &ctx->geo);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
diff --git a/spaceman/file.c b/spaceman/file.c
index 7e33e07e..9e983d79 100644
--- a/spaceman/file.c
+++ b/spaceman/file.c
@@ -6,6 +6,7 @@
  */
 
 #include "libxfs.h"
+#include "xfrog.h"
 #include <sys/mman.h>
 #include "command.h"
 #include "input.h"
@@ -56,7 +57,7 @@ openfile(
 		return -1;
 	}
 
-	if (ioctl(fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
+	if (xfrog_geometry(fd, geom)) {
 		if (errno == ENOTTY)
 			fprintf(stderr,
 _("%s: Not on a mounted XFS filesystem.\n"),
diff --git a/spaceman/info.c b/spaceman/info.c
index 01d0744a..e4dedee2 100644
--- a/spaceman/info.c
+++ b/spaceman/info.c
@@ -4,6 +4,7 @@
  * Author: Darrick J. Wong <darrick.wong@oracle.com>
  */
 #include "libxfs.h"
+#include "xfrog.h"
 #include "command.h"
 #include "init.h"
 #include "path.h"
@@ -37,24 +38,14 @@ info_f(
 	}
 
 	/* get the current filesystem size & geometry */
-	error = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &geo);
+	error = xfrog_geometry(file->fd, &geo);
 	if (error) {
-		/*
-		 * OK, new xfsctl barfed - back off and try earlier version
-		 * as we're probably running an older kernel version.
-		 * Only field added in the v2 geometry xfsctl is "logsunit"
-		 * so we'll zero that out for later display (as zero).
-		 */
-		geo.logsunit = 0;
-		error = ioctl(file->fd, XFS_IOC_FSGEOMETRY_V1, &geo);
-		if (error) {
-			fprintf(stderr, _(
-				"%s: cannot determine geometry of filesystem"
-				" mounted at %s: %s\n"),
-				progname, file->name, strerror(errno));
-			exitcode = 1;
-			return 0;
-		}
+		fprintf(stderr, _(
+			"%s: cannot determine geometry of filesystem"
+			" mounted at %s: %s\n"),
+			progname, file->name, strerror(errno));
+		exitcode = 1;
+		return 0;
 	}
 
 	xfs_report_geom(&geo, file->fs_path.fs_name, file->fs_path.fs_log,

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 04/12] libfrog: introduce xfrog context
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (2 preceding siblings ...)
  2019-06-20 16:49 ` [PATCH 03/12] libfrog: refactor online geometry queries Darrick J. Wong
@ 2019-06-20 16:49 ` Darrick J. Wong
  2019-06-20 19:40   ` Eric Sandeen
  2019-06-20 16:50 ` [PATCH 05/12] libfrog: store more inode and block geometry in struct xfrog Darrick J. Wong
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:49 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Introduce a new "xfrog" context structure where we can store a file
descriptor and all the runtime fs context (geometry, which ioctls work,
etc.) that goes with it.  We're going to create wrappers for the
bulkstat and inumbers ioctls in subsequent patches; and when we
introduce the v5 bulkstat/inumbers ioctls we'll need all that context to
downgrade gracefully on old kernels.  Start the transition by adopting
xfrog natively in scrub.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfrog.h    |   20 ++++++++++++++++++++
 libfrog/fsgeom.c   |   25 +++++++++++++++++++++++++
 scrub/fscounters.c |   22 ++++++++++++----------
 scrub/inodes.c     |   10 +++++-----
 scrub/phase1.c     |   41 ++++++++++++++++++++---------------------
 scrub/phase2.c     |    2 +-
 scrub/phase3.c     |    4 ++--
 scrub/phase4.c     |    8 ++++----
 scrub/phase5.c     |    2 +-
 scrub/phase6.c     |    6 +++---
 scrub/phase7.c     |    2 +-
 scrub/repair.c     |    4 ++--
 scrub/scrub.c      |   12 ++++++------
 scrub/spacemap.c   |   12 ++++++------
 scrub/vfs.c        |    2 +-
 scrub/xfs_scrub.h  |    7 ++++---
 16 files changed, 113 insertions(+), 66 deletions(-)


diff --git a/include/xfrog.h b/include/xfrog.h
index 5420b47c..e450ee1d 100644
--- a/include/xfrog.h
+++ b/include/xfrog.h
@@ -19,4 +19,24 @@
 struct xfs_fsop_geom;
 int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
 
+/*
+ * Structure for recording whatever observations we want about the level of
+ * xfs runtime support for this fd.  Right now we only store the fd and fs
+ * geometry.
+ */
+struct xfrog {
+	/* ioctl file descriptor */
+	int			fd;
+
+	/* filesystem geometry */
+	struct xfs_fsop_geom	fsgeom;
+};
+
+/* Static initializers */
+#define XFROG_INIT(_fd)		{ .fd = (_fd), }
+#define XFROG_INIT_EMPTY	XFROG_INIT(-1)
+
+int xfrog_prepare_geometry(struct xfrog *froggie);
+int xfrog_close(struct xfrog *froggie);
+
 #endif	/* __XFROG_H__ */
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index a6dab3a8..bf76b520 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -85,3 +85,28 @@ xfrog_geometry(
 
 	return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
 }
+
+/*
+ * Prepare xfrog structure for future ioctl operations by computing the xfs
+ * geometry for @froggie->fd.
+ */
+int
+xfrog_prepare_geometry(
+	struct xfrog		*froggie)
+{
+	return xfrog_geometry(froggie->fd, &froggie->fsgeom);
+}
+
+/* Release any resources associated with this xfrog structure. */
+int
+xfrog_close(
+	struct xfrog		*froggie)
+{
+	int			ret = 0;
+
+	if (froggie->fd >= 0)
+		ret = close(froggie->fd);
+
+	froggie->fd = -1;
+	return ret;
+}
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index 9e93e2a6..f18d0e19 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -57,10 +57,10 @@ xfs_count_inodes_range(
 	igrpreq.ocount  = &igrplen;
 
 	igrp_ino = first_ino;
-	error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
+	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);
+		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
 	}
 
 	if (error) {
@@ -113,7 +113,7 @@ xfs_count_all_inodes(
 	int			ret;
 
 	ci = calloc(1, sizeof(struct xfs_count_inodes) +
-			(ctx->geo.agcount * sizeof(uint64_t)));
+			(ctx->mnt.fsgeom.agcount * sizeof(uint64_t)));
 	if (!ci)
 		return false;
 	ci->moveon = true;
@@ -125,7 +125,7 @@ xfs_count_all_inodes(
 		str_info(ctx, ctx->mntpoint, _("Could not create workqueue."));
 		goto out_free;
 	}
-	for (agno = 0; agno < ctx->geo.agcount; agno++) {
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
 		ret = workqueue_add(&wq, xfs_count_ag_inodes, agno, ci);
 		if (ret) {
 			moveon = false;
@@ -136,7 +136,7 @@ _("Could not queue AG %u icount work."), agno);
 	}
 	workqueue_destroy(&wq);
 
-	for (agno = 0; agno < ctx->geo.agcount; agno++)
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++)
 		*count += ci->counters[agno];
 	moveon = ci->moveon;
 
@@ -162,14 +162,14 @@ xfs_scan_estimate_blocks(
 	int				error;
 
 	/* Grab the fstatvfs counters, since it has to report accurately. */
-	error = fstatvfs(ctx->mnt_fd, &sfs);
+	error = fstatvfs(ctx->mnt.fd, &sfs);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
 
 	/* Fetch the filesystem counters. */
-	error = ioctl(ctx->mnt_fd, XFS_IOC_FSCOUNTS, &fc);
+	error = ioctl(ctx->mnt.fd, XFS_IOC_FSCOUNTS, &fc);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
@@ -179,14 +179,16 @@ xfs_scan_estimate_blocks(
 	 * XFS reserves some blocks to prevent hard ENOSPC, so add those
 	 * blocks back to the free data counts.
 	 */
-	error = ioctl(ctx->mnt_fd, XFS_IOC_GET_RESBLKS, &rb);
+	error = ioctl(ctx->mnt.fd, XFS_IOC_GET_RESBLKS, &rb);
 	if (error)
 		str_errno(ctx, ctx->mntpoint);
 	sfs.f_bfree += rb.resblks_avail;
 
-	*d_blocks = sfs.f_blocks + (ctx->geo.logstart ? ctx->geo.logblocks : 0);
+	*d_blocks = sfs.f_blocks;
+	if (ctx->mnt.fsgeom.logstart > 0)
+		*d_blocks += ctx->mnt.fsgeom.logblocks;
 	*d_bfree = sfs.f_bfree;
-	*r_blocks = ctx->geo.rtblocks;
+	*r_blocks = ctx->mnt.fsgeom.rtblocks;
 	*r_bfree = fc.freertx;
 	*f_files = sfs.f_files;
 	*f_free = sfs.f_ffree;
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 442a5978..08f3d847 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -72,7 +72,7 @@ xfs_iterate_inodes_range_check(
 		/* Load the one inode. */
 		oneino = inogrp->xi_startino + i;
 		onereq.ubuffer = bs;
-		error = ioctl(ctx->mnt_fd, XFS_IOC_FSBULKSTAT_SINGLE,
+		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT_SINGLE,
 				&onereq);
 		if (error || bs->bs_ino != inogrp->xi_startino + i) {
 			memset(bs, 0, sizeof(struct xfs_bstat));
@@ -134,7 +134,7 @@ xfs_iterate_inodes_range(
 
 	/* Find the inode chunk & alloc mask */
 	igrp_ino = first_ino;
-	error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
+	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
 	while (!error && igrplen) {
 		/* Load the inodes. */
 		ino = inogrp.xi_startino - 1;
@@ -145,7 +145,7 @@ xfs_iterate_inodes_range(
 		 */
 		if (inogrp.xi_alloccount == 0)
 			goto igrp_retry;
-		error = ioctl(ctx->mnt_fd, XFS_IOC_FSBULKSTAT, &bulkreq);
+		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT, &bulkreq);
 		if (error)
 			str_info(ctx, descr, "%s", strerror_r(errno,
 						buf, DESCR_BUFSZ));
@@ -190,7 +190,7 @@ _("Changed too many times during scan; giving up."));
 
 		stale_count = 0;
 igrp_retry:
-		error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
+		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
 	}
 
 err:
@@ -260,7 +260,7 @@ xfs_scan_all_inodes(
 		return false;
 	}
 
-	for (agno = 0; agno < ctx->geo.agcount; agno++) {
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
 		ret = workqueue_add(&wq, xfs_scan_ag_inodes, agno, &si);
 		if (ret) {
 			si.moveon = false;
diff --git a/scrub/phase1.c b/scrub/phase1.c
index 5ab2a4fe..c7034527 100644
--- a/scrub/phase1.c
+++ b/scrub/phase1.c
@@ -39,7 +39,7 @@ xfs_shutdown_fs(
 
 	flag = XFS_FSOP_GOING_FLAGS_LOGFLUSH;
 	str_info(ctx, ctx->mntpoint, _("Shutting down filesystem!"));
-	if (ioctl(ctx->mnt_fd, XFS_IOC_GOINGDOWN, &flag))
+	if (ioctl(ctx->mnt.fd, XFS_IOC_GOINGDOWN, &flag))
 		str_errno(ctx, ctx->mntpoint);
 }
 
@@ -60,11 +60,9 @@ xfs_cleanup_fs(
 	if (ctx->datadev)
 		disk_close(ctx->datadev);
 	fshandle_destroy();
-	if (ctx->mnt_fd >= 0) {
-		error = close(ctx->mnt_fd);
-		if (error)
-			str_errno(ctx, _("closing mountpoint fd"));
-	}
+	error = xfrog_close(&ctx->mnt);
+	if (error)
+		str_errno(ctx, _("closing mountpoint fd"));
 	fs_table_destroy();
 
 	return true;
@@ -86,8 +84,8 @@ xfs_setup_fs(
 	 * CAP_SYS_ADMIN, which we probably need to do anything fancy
 	 * with the (XFS driver) kernel.
 	 */
-	ctx->mnt_fd = open(ctx->mntpoint, O_RDONLY | O_NOATIME | O_DIRECTORY);
-	if (ctx->mnt_fd < 0) {
+	ctx->mnt.fd = open(ctx->mntpoint, O_RDONLY | O_NOATIME | O_DIRECTORY);
+	if (ctx->mnt.fd < 0) {
 		if (errno == EPERM)
 			str_info(ctx, ctx->mntpoint,
 _("Must be root to run scrub."));
@@ -96,23 +94,23 @@ _("Must be root to run scrub."));
 		return false;
 	}
 
-	error = fstat(ctx->mnt_fd, &ctx->mnt_sb);
+	error = fstat(ctx->mnt.fd, &ctx->mnt_sb);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
-	error = fstatvfs(ctx->mnt_fd, &ctx->mnt_sv);
+	error = fstatvfs(ctx->mnt.fd, &ctx->mnt_sv);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
-	error = fstatfs(ctx->mnt_fd, &ctx->mnt_sf);
+	error = fstatfs(ctx->mnt.fd, &ctx->mnt_sf);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
 
-	if (!platform_test_xfs_fd(ctx->mnt_fd)) {
+	if (!platform_test_xfs_fd(ctx->mnt.fd)) {
 		str_info(ctx, ctx->mntpoint,
 _("Does not appear to be an XFS filesystem!"));
 		return false;
@@ -123,27 +121,28 @@ _("Does not appear to be an XFS filesystem!"));
 	 * This seems to reduce the incidence of stale file handle
 	 * errors when we open things by handle.
 	 */
-	error = syncfs(ctx->mnt_fd);
+	error = syncfs(ctx->mnt.fd);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
 
-	/* Retrieve XFS geometry. */
-	error = xfrog_geometry(ctx->mnt_fd, &ctx->geo);
+	/* Set up xfrog and compute XFS geometry. */
+	error = xfrog_prepare_geometry(&ctx->mnt);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
 	}
 
-	if (!xfs_action_lists_alloc(ctx->geo.agcount, &ctx->action_lists)) {
+	if (!xfs_action_lists_alloc(ctx->mnt.fsgeom.agcount,
+				&ctx->action_lists)) {
 		str_error(ctx, ctx->mntpoint, _("Not enough memory."));
 		return false;
 	}
 
-	ctx->agblklog = log2_roundup(ctx->geo.agblocks);
-	ctx->blocklog = highbit32(ctx->geo.blocksize);
-	ctx->inodelog = highbit32(ctx->geo.inodesize);
+	ctx->agblklog = log2_roundup(ctx->mnt.fsgeom.agblocks);
+	ctx->blocklog = highbit32(ctx->mnt.fsgeom.blocksize);
+	ctx->inodelog = highbit32(ctx->mnt.fsgeom.inodesize);
 	ctx->inopblog = ctx->blocklog - ctx->inodelog;
 
 	error = path_to_fshandle(ctx->mntpoint, &ctx->fshandle,
@@ -171,12 +170,12 @@ _("Kernel metadata repair facility is not available.  Use -n to scrub."));
 	}
 
 	/* Did we find the log and rt devices, if they're present? */
-	if (ctx->geo.logstart == 0 && ctx->fsinfo.fs_log == NULL) {
+	if (ctx->mnt.fsgeom.logstart == 0 && ctx->fsinfo.fs_log == NULL) {
 		str_info(ctx, ctx->mntpoint,
 _("Unable to find log device path."));
 		return false;
 	}
-	if (ctx->geo.rtblocks && ctx->fsinfo.fs_rt == NULL) {
+	if (ctx->mnt.fsgeom.rtblocks && ctx->fsinfo.fs_rt == NULL) {
 		str_info(ctx, ctx->mntpoint,
 _("Unable to find realtime device path."));
 		return false;
diff --git a/scrub/phase2.c b/scrub/phase2.c
index 653f666c..a80da7fd 100644
--- a/scrub/phase2.c
+++ b/scrub/phase2.c
@@ -141,7 +141,7 @@ xfs_scan_metadata(
 	if (!moveon)
 		goto out;
 
-	for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
+	for (agno = 0; moveon && agno < ctx->mnt.fsgeom.agcount; agno++) {
 		ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
 		if (ret) {
 			moveon = false;
diff --git a/scrub/phase3.c b/scrub/phase3.c
index 4963d675..a42d8213 100644
--- a/scrub/phase3.c
+++ b/scrub/phase3.c
@@ -33,7 +33,7 @@ xfs_scrub_fd(
 	struct xfs_bstat	*bs,
 	struct xfs_action_list	*alist)
 {
-	return fn(ctx, bs->bs_ino, bs->bs_gen, ctx->mnt_fd, alist);
+	return fn(ctx, bs->bs_ino, bs->bs_gen, ctx->mnt.fd, alist);
 }
 
 struct scrub_inode_ctx {
@@ -115,7 +115,7 @@ xfs_scrub_inode(
 	if (S_ISLNK(bstat->bs_mode)) {
 		/* Check symlink contents. */
 		moveon = xfs_scrub_symlink(ctx, bstat->bs_ino,
-				bstat->bs_gen, ctx->mnt_fd, &alist);
+				bstat->bs_gen, ctx->mnt.fd, &alist);
 	} else if (S_ISDIR(bstat->bs_mode)) {
 		/* Check the directory entries. */
 		moveon = xfs_scrub_fd(ctx, xfs_scrub_dir, bstat, &alist);
diff --git a/scrub/phase4.c b/scrub/phase4.c
index 79248326..49f00723 100644
--- a/scrub/phase4.c
+++ b/scrub/phase4.c
@@ -40,7 +40,7 @@ xfs_repair_ag(
 
 	/* Repair anything broken until we fail to make progress. */
 	do {
-		moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist, flags);
+		moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist, flags);
 		if (!moveon) {
 			*pmoveon = false;
 			return;
@@ -56,7 +56,7 @@ xfs_repair_ag(
 
 	/* Try once more, but this time complain if we can't fix things. */
 	flags |= ALP_COMPLAIN_IF_UNFIXED;
-	moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist, flags);
+	moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist, flags);
 	if (!moveon)
 		*pmoveon = false;
 }
@@ -77,7 +77,7 @@ xfs_process_action_items(
 		str_error(ctx, ctx->mntpoint, _("Could not create workqueue."));
 		return false;
 	}
-	for (agno = 0; agno < ctx->geo.agcount; agno++) {
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
 		if (xfs_action_list_length(&ctx->action_lists[agno]) > 0) {
 			ret = workqueue_add(&wq, xfs_repair_ag, agno, &moveon);
 			if (ret) {
@@ -121,7 +121,7 @@ xfs_estimate_repair_work(
 	xfs_agnumber_t		agno;
 	size_t			need_fixing = 0;
 
-	for (agno = 0; agno < ctx->geo.agcount; agno++)
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++)
 		need_fixing += xfs_action_list_length(&ctx->action_lists[agno]);
 	need_fixing++;
 	*items = need_fixing;
diff --git a/scrub/phase5.c b/scrub/phase5.c
index 1743119d..748885d4 100644
--- a/scrub/phase5.c
+++ b/scrub/phase5.c
@@ -306,7 +306,7 @@ xfs_scrub_fs_label(
 		return false;
 
 	/* Retrieve label; quietly bail if we don't support that. */
-	error = ioctl(ctx->mnt_fd, FS_IOC_GETFSLABEL, &label);
+	error = ioctl(ctx->mnt.fd, FS_IOC_GETFSLABEL, &label);
 	if (error) {
 		if (errno != EOPNOTSUPP && errno != ENOTTY) {
 			moveon = false;
diff --git a/scrub/phase6.c b/scrub/phase6.c
index 66e6451c..e5a0b3c1 100644
--- a/scrub/phase6.c
+++ b/scrub/phase6.c
@@ -468,7 +468,7 @@ xfs_scan_blocks(
 	}
 
 	vs.rvp_data = read_verify_pool_init(ctx, ctx->datadev,
-			ctx->geo.blocksize, xfs_check_rmap_ioerr,
+			ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
 			scrub_nproc(ctx));
 	if (!vs.rvp_data) {
 		str_info(ctx, ctx->mntpoint,
@@ -477,7 +477,7 @@ _("Could not create data device media verifier."));
 	}
 	if (ctx->logdev) {
 		vs.rvp_log = read_verify_pool_init(ctx, ctx->logdev,
-				ctx->geo.blocksize, xfs_check_rmap_ioerr,
+				ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
 				scrub_nproc(ctx));
 		if (!vs.rvp_log) {
 			str_info(ctx, ctx->mntpoint,
@@ -487,7 +487,7 @@ _("Could not create data device media verifier."));
 	}
 	if (ctx->rtdev) {
 		vs.rvp_realtime = read_verify_pool_init(ctx, ctx->rtdev,
-				ctx->geo.blocksize, xfs_check_rmap_ioerr,
+				ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
 				scrub_nproc(ctx));
 		if (!vs.rvp_realtime) {
 			str_info(ctx, ctx->mntpoint,
diff --git a/scrub/phase7.c b/scrub/phase7.c
index 0c3202e4..13959ca8 100644
--- a/scrub/phase7.c
+++ b/scrub/phase7.c
@@ -111,7 +111,7 @@ xfs_scan_summary(
 	int			error;
 
 	/* Flush everything out to disk before we start counting. */
-	error = syncfs(ctx->mnt_fd);
+	error = syncfs(ctx->mnt.fd);
 	if (error) {
 		str_errno(ctx, ctx->mntpoint);
 		return false;
diff --git a/scrub/repair.c b/scrub/repair.c
index 4ed3c09a..45450d8c 100644
--- a/scrub/repair.c
+++ b/scrub/repair.c
@@ -262,7 +262,7 @@ xfs_action_list_defer(
 	xfs_agnumber_t			agno,
 	struct xfs_action_list		*alist)
 {
-	ASSERT(agno < ctx->geo.agcount);
+	ASSERT(agno < ctx->mnt.fsgeom.agcount);
 
 	xfs_action_list_splice(&ctx->action_lists[agno], alist);
 }
@@ -276,7 +276,7 @@ xfs_action_list_process_or_defer(
 {
 	bool				moveon;
 
-	moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist,
+	moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist,
 			ALP_REPAIR_ONLY | ALP_NOPROGRESS);
 	if (!moveon)
 		return moveon;
diff --git a/scrub/scrub.c b/scrub/scrub.c
index 0f0c9639..136ed529 100644
--- a/scrub/scrub.c
+++ b/scrub/scrub.c
@@ -363,7 +363,7 @@ xfs_scrub_metadata(
 		background_sleep();
 
 		/* Check the item. */
-		fix = xfs_check_metadata(ctx, ctx->mnt_fd, &meta, false);
+		fix = xfs_check_metadata(ctx, ctx->mnt.fd, &meta, false);
 		progress_add(1);
 		switch (fix) {
 		case CHECK_ABORT:
@@ -399,7 +399,7 @@ xfs_scrub_primary_super(
 	enum check_outcome		fix;
 
 	/* Check the item. */
-	fix = xfs_check_metadata(ctx, ctx->mnt_fd, &meta, false);
+	fix = xfs_check_metadata(ctx, ctx->mnt.fd, &meta, false);
 	switch (fix) {
 	case CHECK_ABORT:
 		return false;
@@ -460,7 +460,7 @@ xfs_scrub_estimate_ag_work(
 		switch (sc->type) {
 		case ST_AGHEADER:
 		case ST_PERAG:
-			estimate += ctx->geo.agcount;
+			estimate += ctx->mnt.fsgeom.agcount;
 			break;
 		case ST_FS:
 			estimate++;
@@ -605,9 +605,9 @@ __xfs_scrub_test(
 	if (debug_tweak_on("XFS_SCRUB_NO_KERNEL"))
 		return false;
 	if (debug_tweak_on("XFS_SCRUB_FORCE_REPAIR") && !injected) {
-		inject.fd = ctx->mnt_fd;
+		inject.fd = ctx->mnt.fd;
 		inject.errtag = XFS_ERRTAG_FORCE_SCRUB_REPAIR;
-		error = ioctl(ctx->mnt_fd, XFS_IOC_ERROR_INJECTION, &inject);
+		error = ioctl(ctx->mnt.fd, XFS_IOC_ERROR_INJECTION, &inject);
 		if (error == 0)
 			injected = true;
 	}
@@ -615,7 +615,7 @@ __xfs_scrub_test(
 	meta.sm_type = type;
 	if (repair)
 		meta.sm_flags |= XFS_SCRUB_IFLAG_REPAIR;
-	error = ioctl(ctx->mnt_fd, XFS_IOC_SCRUB_METADATA, &meta);
+	error = ioctl(ctx->mnt.fd, XFS_IOC_SCRUB_METADATA, &meta);
 	if (!error)
 		return true;
 	switch (errno) {
diff --git a/scrub/spacemap.c b/scrub/spacemap.c
index d547a041..c3621a3a 100644
--- a/scrub/spacemap.c
+++ b/scrub/spacemap.c
@@ -56,7 +56,7 @@ xfs_iterate_fsmap(
 	memcpy(head->fmh_keys, keys, sizeof(struct fsmap) * 2);
 	head->fmh_count = FSMAP_NR;
 
-	while ((error = ioctl(ctx->mnt_fd, FS_IOC_GETFSMAP, head)) == 0) {
+	while ((error = ioctl(ctx->mnt.fd, FS_IOC_GETFSMAP, head)) == 0) {
 		for (i = 0, p = head->fmh_recs;
 		     i < head->fmh_entries;
 		     i++, p++) {
@@ -107,8 +107,8 @@ xfs_scan_ag_blocks(
 	off64_t			bperag;
 	bool			moveon;
 
-	bperag = (off64_t)ctx->geo.agblocks *
-		 (off64_t)ctx->geo.blocksize;
+	bperag = (off64_t)ctx->mnt.fsgeom.agblocks *
+		 (off64_t)ctx->mnt.fsgeom.blocksize;
 
 	snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u fsmap"),
 				major(ctx->fsinfo.fs_datadev),
@@ -205,7 +205,7 @@ xfs_scan_all_spacemaps(
 	}
 	if (ctx->fsinfo.fs_rt) {
 		ret = workqueue_add(&wq, xfs_scan_rt_blocks,
-				ctx->geo.agcount + 1, &sbx);
+				ctx->mnt.fsgeom.agcount + 1, &sbx);
 		if (ret) {
 			sbx.moveon = false;
 			str_info(ctx, ctx->mntpoint,
@@ -215,7 +215,7 @@ _("Could not queue rtdev fsmap work."));
 	}
 	if (ctx->fsinfo.fs_log) {
 		ret = workqueue_add(&wq, xfs_scan_log_blocks,
-				ctx->geo.agcount + 2, &sbx);
+				ctx->mnt.fsgeom.agcount + 2, &sbx);
 		if (ret) {
 			sbx.moveon = false;
 			str_info(ctx, ctx->mntpoint,
@@ -223,7 +223,7 @@ _("Could not queue logdev fsmap work."));
 			goto out;
 		}
 	}
-	for (agno = 0; agno < ctx->geo.agcount; agno++) {
+	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
 		ret = workqueue_add(&wq, xfs_scan_ag_blocks, agno, &sbx);
 		if (ret) {
 			sbx.moveon = false;
diff --git a/scrub/vfs.c b/scrub/vfs.c
index 8bcc4e79..7b0b5bcd 100644
--- a/scrub/vfs.c
+++ b/scrub/vfs.c
@@ -232,7 +232,7 @@ fstrim(
 	int			error;
 
 	range.len = ULLONG_MAX;
-	error = ioctl(ctx->mnt_fd, FITRIM, &range);
+	error = ioctl(ctx->mnt.fd, FITRIM, &range);
 	if (error && errno != EOPNOTSUPP && errno != ENOTTY)
 		perror(_("fstrim"));
 }
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index a459e4b5..3eb7ed79 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -6,6 +6,8 @@
 #ifndef XFS_SCRUB_XFS_SCRUB_H_
 #define XFS_SCRUB_XFS_SCRUB_H_
 
+#include <xfrog.h>
+
 extern char *progname;
 
 #define _PATH_PROC_MOUNTS	"/proc/mounts"
@@ -53,14 +55,13 @@ struct scrub_ctx {
 	/* How does the user want us to react to errors? */
 	enum error_action	error_action;
 
-	/* fd to filesystem mount point */
-	int			mnt_fd;
+	/* xfrog context for the mount point */
+	struct xfrog		mnt;
 
 	/* Number of threads for metadata scrubbing */
 	unsigned int		nr_io_threads;
 
 	/* XFS specific geometry */
-	struct xfs_fsop_geom	geo;
 	struct fs_path		fsinfo;
 	unsigned int		agblklog;
 	unsigned int		blocklog;

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 05/12] libfrog: store more inode and block geometry in struct xfrog
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (3 preceding siblings ...)
  2019-06-20 16:49 ` [PATCH 04/12] libfrog: introduce xfrog context Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 16:50 ` [PATCH 06/12] libfrog: create online fs geometry converters Darrick J. Wong
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Move the extra AG geometry fields out of scrub and into the libfrog code
so that we can consolidate the geoemtry code in one place.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfrog.h    |   12 ++++++++++++
 libfrog/fsgeom.c   |   13 ++++++++++++-
 scrub/fscounters.c |    4 ++--
 scrub/inodes.c     |    4 ++--
 scrub/phase1.c     |    5 -----
 scrub/phase3.c     |    6 +++---
 scrub/phase5.c     |    4 ++--
 scrub/phase6.c     |    2 +-
 scrub/phase7.c     |    6 +++---
 scrub/xfs_scrub.h  |    4 ----
 10 files changed, 37 insertions(+), 23 deletions(-)


diff --git a/include/xfrog.h b/include/xfrog.h
index e450ee1d..507f27a4 100644
--- a/include/xfrog.h
+++ b/include/xfrog.h
@@ -30,6 +30,18 @@ struct xfrog {
 
 	/* filesystem geometry */
 	struct xfs_fsop_geom	fsgeom;
+
+	/* log2 of sb_agblocks (rounded up) */
+	unsigned int		agblklog;
+
+	/* log2 of sb_blocksize */
+	unsigned int		blocklog;
+
+	/* log2 of sb_inodesize */
+	unsigned int		inodelog;
+
+	/* log2 of sb_inopblock */
+	unsigned int		inopblog;
 };
 
 /* Static initializers */
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index bf76b520..28e4fd62 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -5,6 +5,7 @@
 #include "libxfs.h"
 #include "fsgeom.h"
 #include "xfrog.h"
+#include "libfrog.h"
 
 void
 xfs_report_geom(
@@ -94,7 +95,17 @@ int
 xfrog_prepare_geometry(
 	struct xfrog		*froggie)
 {
-	return xfrog_geometry(froggie->fd, &froggie->fsgeom);
+	int			ret;
+
+	ret = xfrog_geometry(froggie->fd, &froggie->fsgeom);
+	if (ret)
+		return ret;
+
+	froggie->agblklog = log2_roundup(froggie->fsgeom.agblocks);
+	froggie->blocklog = highbit32(froggie->fsgeom.blocksize);
+	froggie->inodelog = highbit32(froggie->fsgeom.inodesize);
+	froggie->inopblog = froggie->blocklog - froggie->inodelog;
+	return 0;
 }
 
 /* Release any resources associated with this xfrog structure. */
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index f18d0e19..ac898764 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -91,8 +91,8 @@ 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);
+	ag_ino = (__u64)agno << (ctx->mnt.inopblog + ctx->mnt.agblklog);
+	next_ag_ino = (__u64)(agno + 1) << (ctx->mnt.inopblog + ctx->mnt.agblklog);
 
 	moveon = xfs_count_inodes_range(ctx, descr, ag_ino, next_ag_ino - 1,
 			&ci->counters[agno]);
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 08f3d847..873ad425 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -228,8 +228,8 @@ xfs_scan_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);
+	ag_ino = (__u64)agno << (ctx->mnt.inopblog + ctx->mnt.agblklog);
+	next_ag_ino = (__u64)(agno + 1) << (ctx->mnt.inopblog + ctx->mnt.agblklog);
 
 	moveon = xfs_iterate_inodes_range(ctx, descr, ctx->fshandle, ag_ino,
 			next_ag_ino - 1, si->fn, si->arg);
diff --git a/scrub/phase1.c b/scrub/phase1.c
index c7034527..9a3d8f05 100644
--- a/scrub/phase1.c
+++ b/scrub/phase1.c
@@ -140,11 +140,6 @@ _("Does not appear to be an XFS filesystem!"));
 		return false;
 	}
 
-	ctx->agblklog = log2_roundup(ctx->mnt.fsgeom.agblocks);
-	ctx->blocklog = highbit32(ctx->mnt.fsgeom.blocksize);
-	ctx->inodelog = highbit32(ctx->mnt.fsgeom.inodesize);
-	ctx->inopblog = ctx->blocklog - ctx->inodelog;
-
 	error = path_to_fshandle(ctx->mntpoint, &ctx->fshandle,
 			&ctx->fshandle_len);
 	if (error) {
diff --git a/scrub/phase3.c b/scrub/phase3.c
index a42d8213..579e08c3 100644
--- a/scrub/phase3.c
+++ b/scrub/phase3.c
@@ -52,8 +52,8 @@ xfs_scrub_inode_vfs_error(
 	xfs_agino_t		agino;
 	int			old_errno = errno;
 
-	agno = bstat->bs_ino / (1ULL << (ctx->inopblog + ctx->agblklog));
-	agino = bstat->bs_ino % (1ULL << (ctx->inopblog + ctx->agblklog));
+	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agino = bstat->bs_ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
 	snprintf(descr, DESCR_BUFSZ, _("inode %"PRIu64" (%u/%u)"),
 			(uint64_t)bstat->bs_ino, agno, agino);
 	errno = old_errno;
@@ -77,7 +77,7 @@ xfs_scrub_inode(
 	int			error;
 
 	xfs_action_list_init(&alist);
-	agno = bstat->bs_ino / (1ULL << (ctx->inopblog + ctx->agblklog));
+	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
 	background_sleep();
 
 	/* Try to open the inode to pin it. */
diff --git a/scrub/phase5.c b/scrub/phase5.c
index 748885d4..36ec27b3 100644
--- a/scrub/phase5.c
+++ b/scrub/phase5.c
@@ -239,8 +239,8 @@ xfs_scrub_connections(
 	int			fd = -1;
 	int			error;
 
-	agno = bstat->bs_ino / (1ULL << (ctx->inopblog + ctx->agblklog));
-	agino = bstat->bs_ino % (1ULL << (ctx->inopblog + ctx->agblklog));
+	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agino = bstat->bs_ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
 	snprintf(descr, DESCR_BUFSZ, _("inode %"PRIu64" (%u/%u)"),
 			(uint64_t)bstat->bs_ino, agno, agino);
 	background_sleep();
diff --git a/scrub/phase6.c b/scrub/phase6.c
index e5a0b3c1..48971270 100644
--- a/scrub/phase6.c
+++ b/scrub/phase6.c
@@ -547,7 +547,7 @@ xfs_estimate_verify_work(
 	if (!moveon)
 		return moveon;
 
-	*items = ((d_blocks - d_bfree) + (r_blocks - r_bfree)) << ctx->blocklog;
+	*items = ((d_blocks - d_bfree) + (r_blocks - r_bfree)) << ctx->mnt.blocklog;
 	*nr_threads = disk_heads(ctx->datadev);
 	*rshift = 20;
 	return moveon;
diff --git a/scrub/phase7.c b/scrub/phase7.c
index 13959ca8..41a77356 100644
--- a/scrub/phase7.c
+++ b/scrub/phase7.c
@@ -148,11 +148,11 @@ xfs_scan_summary(
 	 * filesystem treats them as "free", but since we scanned
 	 * them, we'll consider them used.
 	 */
-	d_bfree -= totalcount.agbytes >> ctx->blocklog;
+	d_bfree -= totalcount.agbytes >> ctx->mnt.blocklog;
 
 	/* Report on what we found. */
-	used_data = (d_blocks - d_bfree) << ctx->blocklog;
-	used_rt = (r_blocks - r_bfree) << ctx->blocklog;
+	used_data = (d_blocks - d_bfree) << ctx->mnt.blocklog;
+	used_rt = (r_blocks - r_bfree) << ctx->mnt.blocklog;
 	used_files = f_files - f_free;
 	stat_data = totalcount.dbytes;
 	stat_rt = totalcount.rbytes;
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index 3eb7ed79..13888f8c 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -63,10 +63,6 @@ struct scrub_ctx {
 
 	/* XFS specific geometry */
 	struct fs_path		fsinfo;
-	unsigned int		agblklog;
-	unsigned int		blocklog;
-	unsigned int		inodelog;
-	unsigned int		inopblog;
 	void			*fshandle;
 	size_t			fshandle_len;
 

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 06/12] libfrog: create online fs geometry converters
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (4 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 05/12] libfrog: store more inode and block geometry in struct xfrog Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 16:50 ` [PATCH 07/12] libfrog: refactor open-coded bulkstat calls Darrick J. Wong
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Create helper functions to perform unit conversions against a runtime
filesystem, then remove the open-coded versions in scrub.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfrog.h    |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 libfrog/fsgeom.c   |    1 +
 scrub/fscounters.c |    4 ++--
 scrub/inodes.c     |    4 ++--
 scrub/phase3.c     |    6 +++---
 scrub/phase5.c     |    4 ++--
 scrub/phase6.c     |    3 ++-
 scrub/phase7.c     |    6 +++---
 8 files changed, 64 insertions(+), 13 deletions(-)


diff --git a/include/xfrog.h b/include/xfrog.h
index 507f27a4..8d7e38df 100644
--- a/include/xfrog.h
+++ b/include/xfrog.h
@@ -42,6 +42,9 @@ struct xfrog {
 
 	/* log2 of sb_inopblock */
 	unsigned int		inopblog;
+
+	/* bits for agino in inum */
+	unsigned int		aginolog;
 };
 
 /* Static initializers */
@@ -51,4 +54,50 @@ struct xfrog {
 int xfrog_prepare_geometry(struct xfrog *froggie);
 int xfrog_close(struct xfrog *froggie);
 
+/* Convert AG number and AG inode number into fs inode number. */
+static inline uint64_t
+xfrog_agino_to_ino(
+	struct xfrog		*frog,
+	uint32_t		agno,
+	uint32_t		agino)
+{
+	return ((uint64_t)agno << frog->aginolog) + agino;
+}
+
+/* Convert fs inode number into AG number. */
+static inline uint32_t
+xfrog_ino_to_agno(
+	struct xfrog		*frog,
+	uint64_t		ino)
+{
+	return ino >> frog->aginolog;
+}
+
+/* Convert fs inode number into AG inode number. */
+static inline uint32_t
+xfrog_ino_to_agino(
+	struct xfrog		*frog,
+	uint64_t		ino)
+{
+	return ino & ((1ULL << frog->aginolog) - 1);
+}
+
+/* Convert fs block number into bytes */
+static inline uint64_t
+xfrog_fsb_to_b(
+	struct xfrog		*frog,
+	uint64_t		fsb)
+{
+	return fsb << frog->blocklog;
+}
+
+/* Convert bytes into (rounded down) fs block number */
+static inline uint64_t
+xfrog_b_to_fsbt(
+	struct xfrog		*frog,
+	uint64_t		bytes)
+{
+	return bytes >> frog->blocklog;
+}
+
 #endif	/* __XFROG_H__ */
diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
index 28e4fd62..c61466e2 100644
--- a/libfrog/fsgeom.c
+++ b/libfrog/fsgeom.c
@@ -105,6 +105,7 @@ xfrog_prepare_geometry(
 	froggie->blocklog = highbit32(froggie->fsgeom.blocksize);
 	froggie->inodelog = highbit32(froggie->fsgeom.inodesize);
 	froggie->inopblog = froggie->blocklog - froggie->inodelog;
+	froggie->aginolog = froggie->agblklog + froggie->inopblog;
 	return 0;
 }
 
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index ac898764..adb79b50 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -91,8 +91,8 @@ xfs_count_ag_inodes(
 				minor(ctx->fsinfo.fs_datadev),
 				agno);
 
-	ag_ino = (__u64)agno << (ctx->mnt.inopblog + ctx->mnt.agblklog);
-	next_ag_ino = (__u64)(agno + 1) << (ctx->mnt.inopblog + ctx->mnt.agblklog);
+	ag_ino = xfrog_agino_to_ino(&ctx->mnt, agno, 0);
+	next_ag_ino = xfrog_agino_to_ino(&ctx->mnt, agno + 1, 0);
 
 	moveon = xfs_count_inodes_range(ctx, descr, ag_ino, next_ag_ino - 1,
 			&ci->counters[agno]);
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 873ad425..a9000218 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -228,8 +228,8 @@ xfs_scan_ag_inodes(
 				minor(ctx->fsinfo.fs_datadev),
 				agno);
 
-	ag_ino = (__u64)agno << (ctx->mnt.inopblog + ctx->mnt.agblklog);
-	next_ag_ino = (__u64)(agno + 1) << (ctx->mnt.inopblog + ctx->mnt.agblklog);
+	ag_ino = xfrog_agino_to_ino(&ctx->mnt, agno, 0);
+	next_ag_ino = xfrog_agino_to_ino(&ctx->mnt, agno + 1, 0);
 
 	moveon = xfs_iterate_inodes_range(ctx, descr, ctx->fshandle, ag_ino,
 			next_ag_ino - 1, si->fn, si->arg);
diff --git a/scrub/phase3.c b/scrub/phase3.c
index 579e08c3..def9a0de 100644
--- a/scrub/phase3.c
+++ b/scrub/phase3.c
@@ -52,8 +52,8 @@ xfs_scrub_inode_vfs_error(
 	xfs_agino_t		agino;
 	int			old_errno = errno;
 
-	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
-	agino = bstat->bs_ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agno = xfrog_ino_to_agno(&ctx->mnt, bstat->bs_ino);
+	agino = xfrog_ino_to_agino(&ctx->mnt, bstat->bs_ino);
 	snprintf(descr, DESCR_BUFSZ, _("inode %"PRIu64" (%u/%u)"),
 			(uint64_t)bstat->bs_ino, agno, agino);
 	errno = old_errno;
@@ -77,7 +77,7 @@ xfs_scrub_inode(
 	int			error;
 
 	xfs_action_list_init(&alist);
-	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agno = xfrog_ino_to_agno(&ctx->mnt, bstat->bs_ino);
 	background_sleep();
 
 	/* Try to open the inode to pin it. */
diff --git a/scrub/phase5.c b/scrub/phase5.c
index 36ec27b3..2189c9e4 100644
--- a/scrub/phase5.c
+++ b/scrub/phase5.c
@@ -239,8 +239,8 @@ xfs_scrub_connections(
 	int			fd = -1;
 	int			error;
 
-	agno = bstat->bs_ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
-	agino = bstat->bs_ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agno = xfrog_ino_to_agno(&ctx->mnt, bstat->bs_ino);
+	agino = xfrog_ino_to_agino(&ctx->mnt, bstat->bs_ino);
 	snprintf(descr, DESCR_BUFSZ, _("inode %"PRIu64" (%u/%u)"),
 			(uint64_t)bstat->bs_ino, agno, agino);
 	background_sleep();
diff --git a/scrub/phase6.c b/scrub/phase6.c
index 48971270..630d15b0 100644
--- a/scrub/phase6.c
+++ b/scrub/phase6.c
@@ -547,7 +547,8 @@ xfs_estimate_verify_work(
 	if (!moveon)
 		return moveon;
 
-	*items = ((d_blocks - d_bfree) + (r_blocks - r_bfree)) << ctx->mnt.blocklog;
+	*items = xfrog_fsb_to_b(&ctx->mnt,
+			(d_blocks - d_bfree) + (r_blocks - r_bfree));
 	*nr_threads = disk_heads(ctx->datadev);
 	*rshift = 20;
 	return moveon;
diff --git a/scrub/phase7.c b/scrub/phase7.c
index 41a77356..1c459dfc 100644
--- a/scrub/phase7.c
+++ b/scrub/phase7.c
@@ -148,11 +148,11 @@ xfs_scan_summary(
 	 * filesystem treats them as "free", but since we scanned
 	 * them, we'll consider them used.
 	 */
-	d_bfree -= totalcount.agbytes >> ctx->mnt.blocklog;
+	d_bfree -= xfrog_b_to_fsbt(&ctx->mnt, totalcount.agbytes);
 
 	/* Report on what we found. */
-	used_data = (d_blocks - d_bfree) << ctx->mnt.blocklog;
-	used_rt = (r_blocks - r_bfree) << ctx->mnt.blocklog;
+	used_data = xfrog_fsb_to_b(&ctx->mnt, d_blocks - d_bfree);
+	used_rt = xfrog_fsb_to_b(&ctx->mnt, r_blocks - r_bfree);
 	used_files = f_files - f_free;
 	stat_data = totalcount.dbytes;
 	stat_rt = totalcount.rbytes;

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 07/12] libfrog: refactor open-coded bulkstat calls
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (5 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 06/12] libfrog: create online fs geometry converters Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 16:50 ` [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls Darrick J. Wong
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Refactor the BULKSTAT_SINGLE and BULKSTAT ioctl callsites into helper
functions.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fsr/xfs_fsr.c      |  104 ++++++++++++++++++++++------------------------------
 include/xfrog.h    |    7 ++++
 io/open.c          |   70 ++++++++++++++++++-----------------
 io/swapext.c       |   19 ++--------
 libfrog/Makefile   |    1 +
 libfrog/bulkstat.c |   44 ++++++++++++++++++++++
 quota/quot.c       |   29 +++++++--------
 scrub/inodes.c     |   28 ++++----------
 8 files changed, 155 insertions(+), 147 deletions(-)
 create mode 100644 libfrog/bulkstat.c


diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
index 0bfecf37..6c8def57 100644
--- a/fsr/xfs_fsr.c
+++ b/fsr/xfs_fsr.c
@@ -102,31 +102,6 @@ static int	nfrags = 0;	/* Debug option: Coerse into specific number
 				 * of extents */
 static int	openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT;
 
-static int
-xfs_bulkstat_single(int fd, xfs_ino_t *lastip, xfs_bstat_t *ubuffer)
-{
-    xfs_fsop_bulkreq_t  bulkreq;
-
-    bulkreq.lastip = (__u64 *)lastip;
-    bulkreq.icount = 1;
-    bulkreq.ubuffer = ubuffer;
-    bulkreq.ocount = NULL;
-    return ioctl(fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq);
-}
-
-static int
-xfs_bulkstat(int fd, xfs_ino_t *lastip, int icount,
-                    xfs_bstat_t *ubuffer, __s32 *ocount)
-{
-    xfs_fsop_bulkreq_t  bulkreq;
-
-    bulkreq.lastip = (__u64 *)lastip;
-    bulkreq.icount = icount;
-    bulkreq.ubuffer = ubuffer;
-    bulkreq.ocount = ocount;
-    return ioctl(fd, XFS_IOC_FSBULKSTAT, &bulkreq);
-}
-
 static int
 xfs_swapext(int fd, xfs_swapext_t *sx)
 {
@@ -596,11 +571,11 @@ fsrall_cleanup(int timeout)
 static int
 fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
 {
-
-	int	fsfd, fd;
+	struct xfrog	fsfrog = XFROG_INIT_EMPTY;
+	int	fd;
 	int	count = 0;
 	int	ret;
-	__s32	buflenout;
+	uint32_t buflenout;
 	xfs_bstat_t buf[GRABSZ];
 	char	fname[64];
 	char	*tname;
@@ -617,25 +592,27 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
 		return -1;
 	}
 
-	if ((fsfd = open(mntdir, O_RDONLY)) < 0) {
+	if ((fsfrog.fd = open(mntdir, O_RDONLY)) < 0) {
 		fsrprintf(_("unable to open: %s: %s\n"),
 		          mntdir, strerror( errno ));
 		free(fshandlep);
 		return -1;
 	}
 
-	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
+	ret = xfrog_prepare_geometry(&fsfrog);
+	if (ret) {
 		fsrprintf(_("Skipping %s: could not get XFS geometry\n"),
 			  mntdir);
-		close(fsfd);
+		xfrog_close(&fsfrog);
 		free(fshandlep);
 		return -1;
 	}
+	memcpy(&fsgeom, &fsfrog.fsgeom, sizeof(fsgeom));
 
 	tmp_init(mntdir);
 
-	while ((ret = xfs_bulkstat(fsfd,
-				&lastino, GRABSZ, &buf[0], &buflenout)) == 0) {
+	while ((ret = xfrog_bulkstat(&fsfrog, &lastino, GRABSZ, &buf[0],
+				&buflenout)) == 0) {
 		xfs_bstat_t *p;
 		xfs_bstat_t *endp;
 
@@ -684,16 +661,16 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
 		}
 		if (endtime && endtime < time(NULL)) {
 			tmp_close(mntdir);
-			close(fsfd);
+			xfrog_close(&fsfrog);
 			fsrall_cleanup(1);
 			exit(1);
 		}
 	}
 	if (ret < 0)
-		fsrprintf(_("%s: xfs_bulkstat: %s\n"), progname, strerror(errno));
+		fsrprintf(_("%s: xfrog_bulkstat: %s\n"), progname, strerror(errno));
 out0:
 	tmp_close(mntdir);
-	close(fsfd);
+	xfrog_close(&fsfrog);
 	free(fshandlep);
 	return 0;
 }
@@ -726,13 +703,16 @@ fsrdir(char *dirname)
  * an open on the file and passes this all to fsrfile_common.
  */
 static int
-fsrfile(char *fname, xfs_ino_t ino)
+fsrfile(
+	char			*fname,
+	xfs_ino_t		ino)
 {
-	xfs_bstat_t	statbuf;
-	jdm_fshandle_t	*fshandlep;
-	int	fd = -1, fsfd = -1;
-	int	error = -1;
-	char	*tname;
+	struct xfrog		fsfrog = XFROG_INIT_EMPTY;
+	struct xfs_bstat	statbuf;
+	jdm_fshandle_t		*fshandlep;
+	int			fd = -1;
+	int			error = -1;
+	char			*tname;
 
 	fshandlep = jdm_getfshandle(getparent (fname) );
 	if (!fshandlep) {
@@ -745,14 +725,21 @@ fsrfile(char *fname, xfs_ino_t ino)
 	 * Need to open something on the same filesystem as the
 	 * file.  Open the parent.
 	 */
-	fsfd = open(getparent(fname), O_RDONLY);
-	if (fsfd < 0) {
+	fsfrog.fd = open(getparent(fname), O_RDONLY);
+	if (fsfrog.fd < 0) {
 		fsrprintf(_("unable to open sys handle for %s: %s\n"),
 			fname, strerror(errno));
 		goto out;
 	}
 
-	if ((xfs_bulkstat_single(fsfd, &ino, &statbuf)) < 0) {
+	error = xfrog_prepare_geometry(&fsfrog);
+	if (error) {
+		fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
+		goto out;
+	}
+
+	error = xfrog_bulkstat_single(&fsfrog, ino, &statbuf);
+	if (error < 0) {
 		fsrprintf(_("unable to get bstat on %s: %s\n"),
 			fname, strerror(errno));
 		goto out;
@@ -765,11 +752,8 @@ fsrfile(char *fname, xfs_ino_t ino)
 		goto out;
 	}
 
-	/* Get the fs geometry */
-	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
-		fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
-		goto out;
-	}
+	/* Stash the fs geometry for general use. */
+	memcpy(&fsgeom, &fsfrog.fsgeom, sizeof(fsgeom));
 
 	tname = gettmpname(fname);
 
@@ -777,8 +761,7 @@ fsrfile(char *fname, xfs_ino_t ino)
 		error = fsrfile_common(fname, tname, NULL, fd, &statbuf);
 
 out:
-	if (fsfd >= 0)
-		close(fsfd);
+	xfrog_close(&fsfrog);
 	if (fd >= 0)
 		close(fd);
 	free(fshandlep);
@@ -945,6 +928,7 @@ fsr_setup_attr_fork(
 	xfs_bstat_t	*bstatp)
 {
 #ifdef HAVE_FSETXATTR
+	struct xfrog	tfrog = XFROG_INIT(tfd);
 	struct stat	tstatbuf;
 	int		i;
 	int		diff = 0;
@@ -962,7 +946,7 @@ fsr_setup_attr_fork(
 	if (!(fsgeom.flags & XFS_FSOP_GEOM_FLAGS_ATTR2) ||
 	    bstatp->bs_forkoff == 0) {
 		/* attr1 */
-		ret = fsetxattr(tfd, "user.X", "X", 1, XATTR_CREATE);
+		ret = fsetxattr(tfrog.fd, "user.X", "X", 1, XATTR_CREATE);
 		if (ret) {
 			fsrprintf(_("could not set ATTR\n"));
 			return -1;
@@ -972,7 +956,7 @@ fsr_setup_attr_fork(
 
 	/* attr2 w/ fork offsets */
 
-	if (fstat(tfd, &tstatbuf) < 0) {
+	if (fstat(tfrog.fd, &tstatbuf) < 0) {
 		fsrprintf(_("unable to stat temp file: %s\n"),
 					strerror(errno));
 		return -1;
@@ -981,16 +965,16 @@ fsr_setup_attr_fork(
 	i = 0;
 	do {
 		xfs_bstat_t	tbstat;
-		xfs_ino_t	ino;
 		char		name[64];
+		int		ret;
 
 		/*
 		 * bulkstat the temp inode to see what the forkoff is.  Use
 		 * this to compare against the target and determine what we
 		 * need to do.
 		 */
-		ino = tstatbuf.st_ino;
-		if ((xfs_bulkstat_single(tfd, &ino, &tbstat)) < 0) {
+		ret = xfrog_bulkstat_single(&tfrog, tstatbuf.st_ino, &tbstat);
+		if (ret < 0) {
 			fsrprintf(_("unable to get bstat on temp file: %s\n"),
 						strerror(errno));
 			return -1;
@@ -1012,7 +996,7 @@ fsr_setup_attr_fork(
 		 */
 		if (!tbstat.bs_forkoff) {
 			ASSERT(i == 0);
-			ret = fsetxattr(tfd, name, "XX", 2, XATTR_CREATE);
+			ret = fsetxattr(tfrog.fd, name, "XX", 2, XATTR_CREATE);
 			if (ret) {
 				fsrprintf(_("could not set ATTR\n"));
 				return -1;
@@ -1048,7 +1032,7 @@ fsr_setup_attr_fork(
 			if (diff < 0) {
 				char val[2048];
 				memset(val, 'X', 2048);
-				if (fsetxattr(tfd, name, val, 2048, 0)) {
+				if (fsetxattr(tfrog.fd, name, val, 2048, 0)) {
 					fsrprintf(_("big ATTR set failed\n"));
 					return -1;
 				}
@@ -1092,7 +1076,7 @@ fsr_setup_attr_fork(
 		}
 
 		/* we need to grow the attr fork, so create another attr */
-		ret = fsetxattr(tfd, name, "XX", 2, XATTR_CREATE);
+		ret = fsetxattr(tfrog.fd, name, "XX", 2, XATTR_CREATE);
 		if (ret) {
 			fsrprintf(_("could not set ATTR\n"));
 			return -1;
diff --git a/include/xfrog.h b/include/xfrog.h
index 8d7e38df..176a2e1d 100644
--- a/include/xfrog.h
+++ b/include/xfrog.h
@@ -100,4 +100,11 @@ xfrog_b_to_fsbt(
 	return bytes >> frog->blocklog;
 }
 
+/* Bulkstat wrappers */
+struct xfs_bstat;
+int xfrog_bulkstat_single(struct xfrog *froggie, uint64_t ino,
+		struct xfs_bstat *ubuffer);
+int xfrog_bulkstat(struct xfrog *froggie, uint64_t *lastino, uint32_t icount,
+		struct xfs_bstat *ubuffer, uint32_t *ocount);
+
 #endif	/* __XFROG_H__ */
diff --git a/io/open.c b/io/open.c
index 997df119..36e07dc3 100644
--- a/io/open.c
+++ b/io/open.c
@@ -713,19 +713,18 @@ get_last_inode(void)
 
 static int
 inode_f(
-	  int			argc,
-	  char			**argv)
+	int			argc,
+	char			**argv)
 {
-	__s32			count = 0;
-	__u64			result_ino = 0;
-	__u64			userino = NULLFSINO;
+	struct xfs_bstat	bstat;
+	uint32_t		count = 0;
+	uint64_t		result_ino = 0;
+	uint64_t		userino = NULLFSINO;
 	char			*p;
 	int			c;
 	int			verbose = 0;
 	int			ret_next = 0;
-	int			cmd = 0;
-	struct xfs_fsop_bulkreq	bulkreq;
-	struct xfs_bstat	bstat;
+	int			ret;
 
 	while ((c = getopt(argc, argv, "nv")) != EOF) {
 		switch (c) {
@@ -767,35 +766,36 @@ inode_f(
 			exitcode = 1;
 			return 0;
 		}
+	} else if (ret_next) {
+		struct xfrog	frog = XFROG_INIT(file->fd);
+
+		/* get next inode */
+		ret = xfrog_bulkstat(&frog, &userino, 1, &bstat, &count);
+		if (ret) {
+			perror("xfsctl");
+			exitcode = 1;
+			return 0;
+		}
+
+		/* The next inode in use, or 0 if none */
+		if (count)
+			result_ino = bstat.bs_ino;
+		else
+			result_ino = 0;
 	} else {
-		if (ret_next)	/* get next inode */
-			cmd = XFS_IOC_FSBULKSTAT;
-		else		/* get this inode */
-			cmd = XFS_IOC_FSBULKSTAT_SINGLE;
-
-		bulkreq.lastip = &userino;
-		bulkreq.icount = 1;
-		bulkreq.ubuffer = &bstat;
-		bulkreq.ocount = &count;
-
-		if (xfsctl(file->name, file->fd, cmd, &bulkreq)) {
-			if (!ret_next && errno == EINVAL) {
-				/* Not in use */
-				result_ino = 0;
-			} else {
-				perror("xfsctl");
-				exitcode = 1;
-				return 0;
-			}
-		} else if (ret_next) {
-			/* The next inode in use, or 0 if none */
-			if (*bulkreq.ocount)
-				result_ino = bstat.bs_ino;
-			else
-				result_ino = 0;
+		struct xfrog	frog = XFROG_INIT(file->fd);
+
+		/* get this inode */
+		ret = xfrog_bulkstat_single(&frog, userino, &bstat);
+		if (ret && errno == EINVAL) {
+			/* Not in use */
+			result_ino = 0;
+		} else if (ret) {
+			perror("bulkstat_single");
+			exitcode = 1;
+			return 0;
 		} else {
-			/* The inode we asked about */
-			result_ino = userino;
+			result_ino = bstat.bs_ino;
 		}
 	}
 
diff --git a/io/swapext.c b/io/swapext.c
index d360c221..c6ea2252 100644
--- a/io/swapext.c
+++ b/io/swapext.c
@@ -8,6 +8,7 @@
 #include "input.h"
 #include "init.h"
 #include "io.h"
+#include "xfrog.h"
 
 static cmdinfo_t swapext_cmd;
 
@@ -20,26 +21,12 @@ swapext_help(void)
 "\n"));
 }
 
-static int
-xfs_bulkstat_single(
-	int			fd,
-	xfs_ino_t		*lastip,
-	struct xfs_bstat	*ubuffer)
-{
-	struct xfs_fsop_bulkreq	bulkreq;
-
-	bulkreq.lastip = (__u64 *)lastip;
-	bulkreq.icount = 1;
-	bulkreq.ubuffer = ubuffer;
-	bulkreq.ocount = NULL;
-	return ioctl(fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq);
-}
-
 static int
 swapext_f(
 	int			argc,
 	char			**argv)
 {
+	struct xfrog		ffrog = XFROG_INIT(file->fd);
 	int			fd;
 	int			error;
 	struct xfs_swapext	sx;
@@ -60,7 +47,7 @@ swapext_f(
 		goto out;
 	}
 
-	error = xfs_bulkstat_single(file->fd, &stat.st_ino, &sx.sx_stat);
+	error = xfrog_bulkstat_single(&ffrog, stat.st_ino, &sx.sx_stat);
 	if (error) {
 		perror("bulkstat");
 		goto out;
diff --git a/libfrog/Makefile b/libfrog/Makefile
index f5a0539b..05c6f701 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -13,6 +13,7 @@ LT_AGE = 0
 CFILES = \
 avl64.c \
 bitmap.c \
+bulkstat.c \
 convert.c \
 crc32.c \
 fsgeom.c \
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
new file mode 100644
index 00000000..30a9e6bc
--- /dev/null
+++ b/libfrog/bulkstat.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
+ */
+#include "xfs.h"
+#include "xfrog.h"
+
+/* Bulkstat a single inode. */
+int
+xfrog_bulkstat_single(
+	struct xfrog		*froggie,
+	uint64_t		ino,
+	struct xfs_bstat	*ubuffer)
+{
+	__u64			i = ino;
+	struct xfs_fsop_bulkreq	bulkreq = {
+		.lastip		= &i,
+		.icount		= 1,
+		.ubuffer	= ubuffer,
+		.ocount		= NULL,
+	};
+
+	return ioctl(froggie->fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq);
+}
+
+/* Bulkstat a bunch of inodes. */
+int
+xfrog_bulkstat(
+	struct xfrog		*froggie,
+	uint64_t		*lastino,
+	uint32_t		icount,
+	struct xfs_bstat	*ubuffer,
+	uint32_t		*ocount)
+{
+	struct xfs_fsop_bulkreq	bulkreq = {
+		.lastip		= (__u64 *)lastino,
+		.icount		= icount,
+		.ubuffer	= ubuffer,
+		.ocount		= (__s32 *)ocount,
+	};
+
+	return ioctl(froggie->fd, XFS_IOC_FSBULKSTAT, &bulkreq);
+}
diff --git a/quota/quot.c b/quota/quot.c
index d60cf4a8..b076c663 100644
--- a/quota/quot.c
+++ b/quota/quot.c
@@ -11,6 +11,7 @@
 #include <grp.h>
 #include "init.h"
 #include "quota.h"
+#include "xfrog.h"
 
 typedef struct du {
 	struct du	*next;
@@ -124,13 +125,13 @@ quot_bulkstat_add(
 static void
 quot_bulkstat_mount(
 	char			*fsdir,
-	uint			flags)
+	unsigned int		flags)
 {
-	xfs_fsop_bulkreq_t	bulkreq;
-	xfs_bstat_t		*buf;
-	__u64			last = 0;
-	__s32			count;
-	int			i, sts, fsfd;
+	struct xfrog		fsfrog = XFROG_INIT_EMPTY;
+	struct xfs_bstat	*buf;
+	uint64_t		last = 0;
+	uint32_t		count;
+	int			i, sts;
 	du_t			**dp;
 
 	/*
@@ -145,8 +146,8 @@ quot_bulkstat_mount(
 			*dp = NULL;
 	ndu[0] = ndu[1] = ndu[2] = 0;
 
-	fsfd = open(fsdir, O_RDONLY);
-	if (fsfd < 0) {
+	fsfrog.fd = open(fsdir, O_RDONLY);
+	if (fsfrog.fd < 0) {
 		perror(fsdir);
 		return;
 	}
@@ -154,16 +155,12 @@ quot_bulkstat_mount(
 	buf = (xfs_bstat_t *)calloc(NBSTAT, sizeof(xfs_bstat_t));
 	if (!buf) {
 		perror("calloc");
-		close(fsfd);
+		xfrog_close(&fsfrog);
 		return;
 	}
 
-	bulkreq.lastip = &last;
-	bulkreq.icount = NBSTAT;
-	bulkreq.ubuffer = buf;
-	bulkreq.ocount = &count;
-
-	while ((sts = xfsctl(fsdir, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq)) == 0) {
+	while ((sts = xfrog_bulkstat(&fsfrog, &last, NBSTAT, buf,
+				&count)) == 0) {
 		if (count == 0)
 			break;
 		for (i = 0; i < count; i++)
@@ -172,7 +169,7 @@ quot_bulkstat_mount(
 	if (sts < 0)
 		perror("XFS_IOC_FSBULKSTAT"),
 	free(buf);
-	close(fsfd);
+	xfrog_close(&fsfrog);
 }
 
 static int
diff --git a/scrub/inodes.c b/scrub/inodes.c
index a9000218..09dd0055 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -17,6 +17,7 @@
 #include "xfs_scrub.h"
 #include "common.h"
 #include "inodes.h"
+#include "xfrog.h"
 
 /*
  * Iterate a range of inodes.
@@ -50,17 +51,10 @@ xfs_iterate_inodes_range_check(
 	struct xfs_inogrp	*inogrp,
 	struct xfs_bstat	*bstat)
 {
-	struct xfs_fsop_bulkreq	onereq = {NULL};
 	struct xfs_bstat	*bs;
-	__u64			oneino;
-	__s32			onelen = 0;
 	int			i;
 	int			error;
 
-	onereq.lastip  = &oneino;
-	onereq.icount  = 1;
-	onereq.ocount  = &onelen;
-
 	for (i = 0, bs = bstat; i < XFS_INODES_PER_CHUNK; i++) {
 		if (!(inogrp->xi_allocmask & (1ULL << i)))
 			continue;
@@ -70,10 +64,8 @@ xfs_iterate_inodes_range_check(
 		}
 
 		/* Load the one inode. */
-		oneino = inogrp->xi_startino + i;
-		onereq.ubuffer = bs;
-		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT_SINGLE,
-				&onereq);
+		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));
 			bs->bs_ino = inogrp->xi_startino + i;
@@ -99,7 +91,6 @@ xfs_iterate_inodes_range(
 	void			*arg)
 {
 	struct xfs_fsop_bulkreq	igrpreq = {NULL};
-	struct xfs_fsop_bulkreq	bulkreq = {NULL};
 	struct xfs_handle	handle;
 	struct xfs_inogrp	inogrp;
 	struct xfs_bstat	bstat[XFS_INODES_PER_CHUNK];
@@ -107,8 +98,8 @@ xfs_iterate_inodes_range(
 	char			buf[DESCR_BUFSZ];
 	struct xfs_bstat	*bs;
 	__u64			igrp_ino;
-	__u64			ino;
-	__s32			bulklen = 0;
+	uint64_t		ino;
+	uint32_t		bulklen = 0;
 	__s32			igrplen = 0;
 	bool			moveon = true;
 	int			i;
@@ -117,10 +108,6 @@ xfs_iterate_inodes_range(
 
 
 	memset(bstat, 0, XFS_INODES_PER_CHUNK * sizeof(struct xfs_bstat));
-	bulkreq.lastip  = &ino;
-	bulkreq.icount  = XFS_INODES_PER_CHUNK;
-	bulkreq.ubuffer = &bstat;
-	bulkreq.ocount  = &bulklen;
 
 	igrpreq.lastip  = &igrp_ino;
 	igrpreq.icount  = 1;
@@ -138,14 +125,15 @@ xfs_iterate_inodes_range(
 	while (!error && igrplen) {
 		/* Load the inodes. */
 		ino = inogrp.xi_startino - 1;
-		bulkreq.icount = inogrp.xi_alloccount;
+
 		/*
 		 * 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)
 			goto igrp_retry;
-		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT, &bulkreq);
+		error = xfrog_bulkstat(&ctx->mnt, &ino, inogrp.xi_alloccount,
+				bstat, &bulklen);
 		if (error)
 			str_info(ctx, descr, "%s", strerror_r(errno,
 						buf, DESCR_BUFSZ));

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (6 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 07/12] libfrog: refactor open-coded bulkstat calls Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-25 23:53   ` Darrick J. Wong
  2019-06-20 16:50 ` [PATCH 09/12] mkfs: validate start and end of aligned logs Darrick J. Wong
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Refactor all the INUMBERS ioctl callsites into helper functions.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 include/xfrog.h    |    4 ++++
 io/imap.c          |   32 +++++++++++++++-----------------
 io/open.c          |   20 ++++++++------------
 libfrog/bulkstat.c |   19 +++++++++++++++++++
 scrub/fscounters.c |   18 +++++++-----------
 scrub/inodes.c     |   23 +++++++++--------------
 6 files changed, 62 insertions(+), 54 deletions(-)


diff --git a/include/xfrog.h b/include/xfrog.h
index 176a2e1d..dab1214d 100644
--- a/include/xfrog.h
+++ b/include/xfrog.h
@@ -107,4 +107,8 @@ int xfrog_bulkstat_single(struct xfrog *froggie, uint64_t ino,
 int xfrog_bulkstat(struct xfrog *froggie, uint64_t *lastino, uint32_t icount,
 		struct xfs_bstat *ubuffer, uint32_t *ocount);
 
+struct xfs_inogrp;
+int xfrog_inumbers(struct xfrog *froggie, uint64_t *lastino, uint32_t icount,
+		struct xfs_inogrp *ubuffer, uint32_t *ocount);
+
 #endif	/* __XFROG_H__ */
diff --git a/io/imap.c b/io/imap.c
index fbc8e9e1..05a4985d 100644
--- a/io/imap.c
+++ b/io/imap.c
@@ -8,18 +8,20 @@
 #include "input.h"
 #include "init.h"
 #include "io.h"
+#include "xfrog.h"
 
 static cmdinfo_t imap_cmd;
 
 static int
 imap_f(int argc, char **argv)
 {
-	int		count;
-	int		nent;
-	int		i;
-	__u64		last = 0;
-	xfs_inogrp_t	*t;
-	xfs_fsop_bulkreq_t bulkreq;
+	struct xfrog		frog = XFROG_INIT(file->fd);
+	struct xfs_inogrp	*t;
+	uint64_t		last = 0;
+	uint32_t		count;
+	uint32_t		nent;
+	int			i;
+	int			error;
 
 	if (argc != 2)
 		nent = 1;
@@ -30,14 +32,8 @@ imap_f(int argc, char **argv)
 	if (!t)
 		return 0;
 
-	bulkreq.lastip  = &last;
-	bulkreq.icount  = nent;
-	bulkreq.ubuffer = (void *)t;
-	bulkreq.ocount  = &count;
-
-	while (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, &bulkreq) == 0) {
-		if (count == 0)
-			goto out_free;
+	while ((error = xfrog_inumbers(&frog, &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,
@@ -45,9 +41,11 @@ imap_f(int argc, char **argv)
 				(unsigned long long)t[i].xi_allocmask);
 		}
 	}
-	perror("xfsctl(XFS_IOC_FSINUMBERS)");
-	exitcode = 1;
-out_free:
+
+	if (error) {
+		perror("xfsctl(XFS_IOC_FSINUMBERS)");
+		exitcode = 1;
+	}
 	free(t);
 	return 0;
 }
diff --git a/io/open.c b/io/open.c
index 36e07dc3..35bcd23a 100644
--- a/io/open.c
+++ b/io/open.c
@@ -669,24 +669,20 @@ inode_help(void)
 "\n"));
 }
 
+#define IGROUP_NR	(1024)
 static __u64
 get_last_inode(void)
 {
-	__u64			lastip = 0;
-	__u64			lastgrp = 0;
-	__s32			ocount = 0;
+	struct xfrog		frog = XFROG_INIT(file->fd);
+	uint64_t		lastip = 0;
+	uint32_t		lastgrp = 0;
+	uint32_t		ocount = 0;
 	__u64			last_ino;
-	struct xfs_inogrp	igroup[1024];
-	struct xfs_fsop_bulkreq	bulkreq;
-
-	bulkreq.lastip = &lastip;
-	bulkreq.ubuffer = &igroup;
-	bulkreq.icount = sizeof(igroup) / sizeof(struct xfs_inogrp);
-	bulkreq.ocount = &ocount;
+	struct xfs_inogrp	igroup[IGROUP_NR];
 
 	for (;;) {
-		if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS,
-				&bulkreq)) {
+		if (xfrog_inumbers(&frog, &lastip, IGROUP_NR, igroup,
+					&ocount)) {
 			perror("XFS_IOC_FSINUMBERS");
 			return 0;
 		}
diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
index 30a9e6bc..9ce238b8 100644
--- a/libfrog/bulkstat.c
+++ b/libfrog/bulkstat.c
@@ -42,3 +42,22 @@ xfrog_bulkstat(
 
 	return ioctl(froggie->fd, XFS_IOC_FSBULKSTAT, &bulkreq);
 }
+
+/* Query inode allocation bitmask information. */
+int
+xfrog_inumbers(
+	struct xfrog		*froggie,
+	uint64_t		*lastino,
+	uint32_t		icount,
+	struct xfs_inogrp	*ubuffer,
+	uint32_t		*ocount)
+{
+	struct xfs_fsop_bulkreq	bulkreq = {
+		.lastip		= (__u64 *)lastino,
+		.icount		= icount,
+		.ubuffer	= ubuffer,
+		.ocount		= (__s32 *)ocount,
+	};
+
+	return ioctl(froggie->fd, XFS_IOC_FSINUMBERS, &bulkreq);
+}
diff --git a/scrub/fscounters.c b/scrub/fscounters.c
index adb79b50..cd216b30 100644
--- a/scrub/fscounters.c
+++ b/scrub/fscounters.c
@@ -15,6 +15,7 @@
 #include "xfs_scrub.h"
 #include "common.h"
 #include "fscounters.h"
+#include "xfrog.h"
 
 /*
  * Filesystem counter collection routines.  We can count the number of
@@ -41,26 +42,21 @@ xfs_count_inodes_range(
 	uint64_t		last_ino,
 	uint64_t		*count)
 {
-	struct xfs_fsop_bulkreq	igrpreq = {NULL};
 	struct xfs_inogrp	inogrp;
-	__u64			igrp_ino;
+	uint64_t		igrp_ino;
 	uint64_t		nr = 0;
-	__s32			igrplen = 0;
+	uint32_t		igrplen = 0;
 	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;
-
 	igrp_ino = first_ino;
-	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
-	while (!error && igrplen && inogrp.xi_startino < last_ino) {
+	while (!(error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
+			&igrplen))) {
+		if (igrplen == 0 || inogrp.xi_startino >= last_ino)
+			break;
 		nr += inogrp.xi_alloccount;
-		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
 	}
 
 	if (error) {
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 09dd0055..dea925be 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -90,17 +90,16 @@ xfs_iterate_inodes_range(
 	xfs_inode_iter_fn	fn,
 	void			*arg)
 {
-	struct xfs_fsop_bulkreq	igrpreq = {NULL};
 	struct xfs_handle	handle;
 	struct xfs_inogrp	inogrp;
 	struct xfs_bstat	bstat[XFS_INODES_PER_CHUNK];
 	char			idescr[DESCR_BUFSZ];
 	char			buf[DESCR_BUFSZ];
 	struct xfs_bstat	*bs;
-	__u64			igrp_ino;
+	uint64_t		igrp_ino;
 	uint64_t		ino;
 	uint32_t		bulklen = 0;
-	__s32			igrplen = 0;
+	uint32_t		igrplen = 0;
 	bool			moveon = true;
 	int			i;
 	int			error;
@@ -109,11 +108,6 @@ xfs_iterate_inodes_range(
 
 	memset(bstat, 0, XFS_INODES_PER_CHUNK * sizeof(struct xfs_bstat));
 
-	igrpreq.lastip  = &igrp_ino;
-	igrpreq.icount  = 1;
-	igrpreq.ubuffer = &inogrp;
-	igrpreq.ocount  = &igrplen;
-
 	memcpy(&handle.ha_fsid, fshandle, sizeof(handle.ha_fsid));
 	handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
 			sizeof(handle.ha_fid.fid_len);
@@ -121,8 +115,11 @@ xfs_iterate_inodes_range(
 
 	/* Find the inode chunk & alloc mask */
 	igrp_ino = first_ino;
-	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
-	while (!error && igrplen) {
+	while (!(error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
+			&igrplen))) {
+		if (igrplen == 0)
+			break;
+
 		/* Load the inodes. */
 		ino = inogrp.xi_startino - 1;
 
@@ -131,7 +128,7 @@ xfs_iterate_inodes_range(
 		 * there are more than 64 inodes per block.  Skip these.
 		 */
 		if (inogrp.xi_alloccount == 0)
-			goto igrp_retry;
+			continue;
 		error = xfrog_bulkstat(&ctx->mnt, &ino, inogrp.xi_alloccount,
 				bstat, &bulklen);
 		if (error)
@@ -155,7 +152,7 @@ xfs_iterate_inodes_range(
 				stale_count++;
 				if (stale_count < 30) {
 					igrp_ino = inogrp.xi_startino;
-					goto igrp_retry;
+					continue;
 				}
 				snprintf(idescr, DESCR_BUFSZ, "inode %"PRIu64,
 						(uint64_t)bs->bs_ino);
@@ -177,8 +174,6 @@ _("Changed too many times during scan; giving up."));
 		}
 
 		stale_count = 0;
-igrp_retry:
-		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
 	}
 
 err:

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 09/12] mkfs: validate start and end of aligned logs
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (7 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 19:46   ` Eric Sandeen
  2019-06-20 16:50 ` [PATCH 10/12] xfs_io: repair_f should use its own name Darrick J. Wong
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Validate that the start and end of the log stay within a single AG if
we adjust either end to align to stripe units.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 mkfs/xfs_mkfs.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)


diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index ddb25ecc..468b8fde 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -3033,15 +3033,28 @@ align_internal_log(
 	struct xfs_mount	*mp,
 	int			sunit)
 {
+	uint64_t		logend;
+
 	/* round up log start if necessary */
 	if ((cfg->logstart % sunit) != 0)
 		cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
 
+	/* If our log start overlaps the next AG's metadata, fail. */
+	if (!xfs_verify_fsbno(mp, cfg->logstart)) {
+			fprintf(stderr,
+_("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
+  "within an allocation group.\n"),
+			(long long) cfg->logstart);
+		usage();
+	}
+
 	/* round up/down the log size now */
 	align_log_size(cfg, sunit);
 
 	/* check the aligned log still fits in an AG. */
-	if (cfg->logblocks > cfg->agsize - XFS_FSB_TO_AGBNO(mp, cfg->logstart)) {
+	logend = cfg->logstart + cfg->logblocks - 1;
+	if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend) ||
+	    !xfs_verify_fsbno(mp, logend)) {
 		fprintf(stderr,
 _("Due to stripe alignment, the internal log size (%lld) is too large.\n"
   "Must fit within an allocation group.\n"),

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 10/12] xfs_io: repair_f should use its own name
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (8 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 09/12] mkfs: validate start and end of aligned logs Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 19:52   ` Eric Sandeen
  2019-06-20 16:50 ` [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files Darrick J. Wong
  2019-06-20 16:50 ` [PATCH 12/12] xfs_db: add a function to compute btree geometry Darrick J. Wong
  11 siblings, 1 reply; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

If the repair command fails, it should tag the error message with its
own name ("repair").

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 io/scrub.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/io/scrub.c b/io/scrub.c
index 2ff1a6af..052497be 100644
--- a/io/scrub.c
+++ b/io/scrub.c
@@ -293,7 +293,7 @@ repair_ioctl(
 
 	error = ioctl(fd, XFS_IOC_SCRUB_METADATA, &meta);
 	if (error)
-		perror("scrub");
+		perror("repair");
 	if (meta.sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
 		printf(_("Corruption remains.\n"));
 	if (meta.sm_flags & XFS_SCRUB_OFLAG_PREEN)

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (9 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 10/12] xfs_io: repair_f should use its own name Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  2019-06-20 19:53   ` Eric Sandeen
  2019-06-20 16:50 ` [PATCH 12/12] xfs_db: add a function to compute btree geometry Darrick J. Wong
  11 siblings, 1 reply; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Now that we're syncing userspace libxfs/ files with kernel fs/xfs/
files, teach the diff tool to try fs/xfs/xfs_foo.c if
fs/xfs/libxfs/xfs_foo.c doesn't exist.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 tools/libxfs-diff |    1 +
 1 file changed, 1 insertion(+)


diff --git a/tools/libxfs-diff b/tools/libxfs-diff
index fa57c004..c18ad487 100755
--- a/tools/libxfs-diff
+++ b/tools/libxfs-diff
@@ -22,5 +22,6 @@ dir="$(readlink -m "${dir}/..")"
 
 for i in libxfs/xfs*.[ch]; do
 	kfile="${dir}/$i"
+	test -f "${kfile}" || kfile="$(echo "${kfile}" | sed -e 's|libxfs/||g')"
 	diff -Naurpw --label "$i" <(sed -e '/#include/d' "$i") --label "${kfile}" <(sed -e '/#include/d' "${kfile}")
 done

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH 12/12] xfs_db: add a function to compute btree geometry
  2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
                   ` (10 preceding siblings ...)
  2019-06-20 16:50 ` [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files Darrick J. Wong
@ 2019-06-20 16:50 ` Darrick J. Wong
  11 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 16:50 UTC (permalink / raw)
  To: sandeen, darrick.wong; +Cc: linux-xfs

From: Darrick J. Wong <darrick.wong@oracle.com>

Add a new command to xfs_db that uses a btree type and a record count
to report the best and worst case height and level size.  This can be
used to estimate how overhead a metadata index will add to a filesystem.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 db/Makefile              |    2 
 db/btheight.c            |  307 ++++++++++++++++++++++++++++++++++++++++++++++
 db/command.c             |    1 
 db/command.h             |    1 
 libxfs/libxfs_api_defs.h |    2 
 5 files changed, 312 insertions(+), 1 deletion(-)
 create mode 100644 db/btheight.c


diff --git a/db/Makefile b/db/Makefile
index 8fecfc1c..ceedbebd 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -14,7 +14,7 @@ HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \
 	io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \
 	sig.h strvec.h text.h type.h write.h attrset.h symlink.h fsmap.h \
 	fuzz.h
-CFILES = $(HFILES:.h=.c) btdump.c info.c
+CFILES = $(HFILES:.h=.c) btdump.c btheight.c info.c
 LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh
 
 LLDLIBS	= $(LIBXFS) $(LIBXLOG) $(LIBFROG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD)
diff --git a/db/btheight.c b/db/btheight.c
new file mode 100644
index 00000000..df11b347
--- /dev/null
+++ b/db/btheight.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
+ */
+#include "libxfs.h"
+#include "command.h"
+#include "output.h"
+#include "init.h"
+#include "io.h"
+#include "type.h"
+#include "input.h"
+#include "../include/convert.h"
+
+static int refc_maxrecs(struct xfs_mount *mp, int blocklen, int leaf)
+{
+	return libxfs_refcountbt_maxrecs(blocklen, leaf != 0);
+}
+
+static int rmap_maxrecs(struct xfs_mount *mp, int blocklen, int leaf)
+{
+	return libxfs_rmapbt_maxrecs(blocklen, leaf);
+}
+
+struct btmap {
+	const char	*tag;
+	int		(*maxrecs)(struct xfs_mount *mp, int blocklen,
+				   int leaf);
+} maps[] = {
+	{"bnobt", libxfs_allocbt_maxrecs},
+	{"cntbt", libxfs_allocbt_maxrecs},
+	{"inobt", libxfs_inobt_maxrecs},
+	{"finobt", libxfs_inobt_maxrecs},
+	{"bmapbt", libxfs_bmbt_maxrecs},
+	{"refcountbt", refc_maxrecs},
+	{"rmapbt", rmap_maxrecs},
+};
+
+static void
+btheight_help(void)
+{
+	struct btmap	*m;
+	int		i;
+
+	dbprintf(_(
+"\n"
+" For a given number of btree records and a btree type, report the number of\n"
+" records and blocks for each level of the btree, and the total btree size.\n"
+" The btree type must be given after the options.  A raw btree geometry can\n"
+" be provided in the format \"record_bytes:key_bytes:ptr_bytes:header_type\"\n"
+" where header_type is one of \"short\", \"long\", \"shortcrc\", or \"longcrc\".\n"
+"\n"
+" Options:\n"
+"   -b -- Override the btree block size.\n"
+"   -n -- Number of records we want to store.\n"
+"   -w max -- Show only the best case scenario.\n"
+"   -w min -- Show only the worst case scenario.\n"
+"\n"
+" Supported btree types:\n"
+"   "
+));
+	for (i = 0, m = maps; i < ARRAY_SIZE(maps); i++, m++)
+		printf("%s ", m->tag);
+	printf("\n");
+}
+
+static void
+calc_height(
+	unsigned long long	nr_records,
+	uint			*records_per_block)
+{
+	unsigned int		level = 0;
+	unsigned long long	total_blocks = 0;
+	unsigned long long	blocks;
+	char			*levels_suffix = "s";
+	char			*totblocks_suffix = "s";
+
+	while (nr_records) {
+		unsigned int	level_rpb = records_per_block[level != 0];
+		char		*recs_suffix = "s";
+		char		*blocks_suffix = "s";
+
+		blocks = (nr_records + level_rpb - 1) / level_rpb;
+
+		if (nr_records == 1)
+			recs_suffix = "";
+		if (blocks == 1)
+			blocks_suffix = "";
+
+		printf(_("level %u: %llu record%s, %llu block%s\n"),
+				level, nr_records, recs_suffix, blocks,
+				blocks_suffix);
+
+		total_blocks += blocks;
+		nr_records = blocks == 1 ? 0 : blocks;
+		level++;
+	}
+
+	if (level == 1)
+		levels_suffix = "";
+	if (total_blocks == 1)
+		totblocks_suffix = "";
+
+	printf(_("%u level%s, %llu block%s total\n"), level, levels_suffix,
+			total_blocks, totblocks_suffix);
+}
+
+static int
+construct_records_per_block(
+	char		*tag,
+	int		blocksize,
+	unsigned int	*records_per_block)
+{
+	char		*toktag;
+	struct btmap	*m;
+	unsigned int	record_size, key_size, ptr_size;
+	char		*p;
+	int		i, ret;
+
+	for (i = 0, m = maps; i < ARRAY_SIZE(maps); i++, m++) {
+		if (!strcmp(m->tag, tag)) {
+			records_per_block[0] = m->maxrecs(mp, blocksize, 1);
+			records_per_block[1] = m->maxrecs(mp, blocksize, 0);
+			return 0;
+		}
+	}
+
+	toktag = strdup(tag);
+	ret = -1;
+
+	p = strtok(toktag, ":");
+	if (!p) {
+		fprintf(stderr, _("%s: record size not found.\n"), tag);
+		goto out;
+	}
+	record_size = cvt_u16(p, 0);
+	if (errno) {
+		perror(p);
+		goto out;
+	}
+
+	p = strtok(NULL, ":");
+	if (!p) {
+		fprintf(stderr, _("%s: key size not found.\n"), tag);
+		goto out;
+	}
+	key_size = cvt_u16(p, 0);
+	if (errno) {
+		perror(p);
+		goto out;
+	}
+
+	p = strtok(NULL, ":");
+	if (!p) {
+		fprintf(stderr, _("%s: pointer size not found.\n"), tag);
+		goto out;
+	}
+	ptr_size = cvt_u16(p, 0);
+	if (errno) {
+		perror(p);
+		goto out;
+	}
+
+	p = strtok(NULL, ":");
+	if (!p) {
+		fprintf(stderr, _("%s: header type not found.\n"), tag);
+		goto out;
+	}
+	if (!strcmp(p, "short"))
+		blocksize -= XFS_BTREE_SBLOCK_LEN;
+	else if (!strcmp(p, "shortcrc"))
+		blocksize -= XFS_BTREE_SBLOCK_CRC_LEN;
+	else if (!strcmp(p, "long"))
+		blocksize -= XFS_BTREE_LBLOCK_LEN;
+	else if (!strcmp(p, "longcrc"))
+		blocksize -= XFS_BTREE_LBLOCK_CRC_LEN;
+	else {
+		fprintf(stderr, _("%s: unrecognized btree header type."),
+				p);
+		goto out;
+	}
+
+	p = strtok(NULL, ":");
+	if (p) {
+		fprintf(stderr,
+			_("%s: unrecognized raw btree geometry."),
+				tag);
+		goto out;
+	}
+
+	records_per_block[0] = blocksize / record_size;
+	records_per_block[1] = blocksize / (key_size + ptr_size);
+	ret = 0;
+out:
+	free(toktag);
+	return ret;
+}
+
+#define REPORT_DEFAULT	(-1U)
+#define REPORT_MAX	(1 << 0)
+#define REPORT_MIN	(1 << 1)
+
+static void
+report(
+	char			*tag,
+	unsigned int		report_what,
+	unsigned long long	nr_records,
+	unsigned int		blocksize)
+{
+	unsigned int		records_per_block[2];
+	int			ret;
+
+	ret = construct_records_per_block(tag, blocksize, records_per_block);
+	if (ret) {
+		printf(_("%s: Unable to determine records per block.\n"),
+				tag);
+		return;
+	}
+
+	if (report_what & REPORT_MAX) {
+		printf(
+_("%s: best case per %u-byte block: %u records (leaf) / %u keyptrs (node)\n"),
+				tag, blocksize, records_per_block[0],
+				records_per_block[1]);
+
+		calc_height(nr_records, records_per_block);
+	}
+
+	if (report_what & REPORT_MIN) {
+		records_per_block[0] /= 2;
+		records_per_block[1] /= 2;
+
+		printf(
+_("%s: worst case per %u-byte block: %u records (leaf) / %u keyptrs (node)\n"),
+				tag, blocksize, records_per_block[0],
+				records_per_block[1]);
+
+		calc_height(nr_records, records_per_block);
+	}
+}
+
+static int
+btheight_f(
+	int		argc,
+	char		**argv)
+{
+	long long	blocksize = mp->m_sb.sb_blocksize;
+	uint64_t	nr_records = 0;
+	int		report_what = REPORT_DEFAULT;
+	int		i, c;
+
+	while ((c = getopt(argc, argv, "b:n:w:")) != -1) {
+		switch (c) {
+		case 'b':
+			errno = 0;
+			blocksize = cvtnum(mp->m_sb.sb_blocksize,
+					mp->m_sb.sb_sectsize,
+					optarg);
+			if (errno) {
+				perror(optarg);
+				return 0;
+			}
+			break;
+		case 'n':
+			nr_records = cvt_u64(optarg, 0);
+			if (errno) {
+				perror(optarg);
+				return 0;
+			}
+			break;
+		case 'w':
+			if (!strcmp(optarg, "min"))
+				report_what = REPORT_MIN;
+			else if (!strcmp(optarg, "max"))
+				report_what = REPORT_MAX;
+			else {
+				btheight_help();
+				return 0;
+			}
+			break;
+		default:
+			btheight_help();
+			return 0;
+		}
+	}
+
+	if (argc == optind || blocksize <= 0 || blocksize > INT_MAX ||
+	    nr_records == 0) {
+		btheight_help();
+		return 0;
+	}
+
+	for (i = optind; i < argc; i++)
+		report(argv[i], report_what, nr_records, blocksize);
+
+	return 0;
+}
+
+static const cmdinfo_t btheight_cmd =
+	{ "btheight", "b", btheight_f, 1, -1, 0, "[-a] [-i]",
+	  N_("compute btree heights"), btheight_help };
+
+void
+btheight_init(void)
+{
+	add_command(&btheight_cmd);
+}
diff --git a/db/command.c b/db/command.c
index c7c52342..cb9012c2 100644
--- a/db/command.c
+++ b/db/command.c
@@ -114,6 +114,7 @@ init_commands(void)
 	block_init();
 	bmap_init();
 	btdump_init();
+	btheight_init();
 	check_init();
 	convert_init();
 	crc_init();
diff --git a/db/command.h b/db/command.h
index eacfd465..d7c5bbd4 100644
--- a/db/command.h
+++ b/db/command.h
@@ -30,3 +30,4 @@ extern void		init_commands(void);
 
 extern void		btdump_init(void);
 extern void		info_init(void);
+extern void		btheight_init(void);
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index 71a7ef53..fff160ef 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -124,6 +124,8 @@
 #define xfs_dir_ino_validate		libxfs_dir_ino_validate
 #define xfs_initialize_perag_data	libxfs_initialize_perag_data
 #define xfs_inobt_maxrecs		libxfs_inobt_maxrecs
+#define xfs_rmapbt_maxrecs		libxfs_rmapbt_maxrecs
+#define xfs_refcountbt_maxrecs		libxfs_refcountbt_maxrecs
 #define xfs_iread_extents		libxfs_iread_extents
 #define xfs_log_calc_minimum_size	libxfs_log_calc_minimum_size
 #define xfs_perag_get			libxfs_perag_get

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/12] libfrog: don't set negative errno in conversion functions
  2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
@ 2019-06-20 18:58   ` Eric Sandeen
  2019-06-25 11:02   ` Christoph Hellwig
  1 sibling, 0 replies; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 18:58 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:49 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Don't set errno to a negative value when we're converting integers.
> That's a kernel thing; this is userspace.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

<Doge stare>

and it's also "errno" fercryingoutloud ;)

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  libfrog/convert.c |   12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> 
> diff --git a/libfrog/convert.c b/libfrog/convert.c
> index ed4cae7f..62397507 100644
> --- a/libfrog/convert.c
> +++ b/libfrog/convert.c
> @@ -47,7 +47,7 @@ cvt_s64(
>  		return i;
>  
>  	/* Not all the input was consumed, return error. */
> -	errno = -ERANGE;
> +	errno = ERANGE;
>  	return INT64_MIN;
>  }
>  
> @@ -68,7 +68,7 @@ cvt_s32(
>  	if (errno)
>  		return i;
>  	if (i > INT32_MAX || i < INT32_MIN) {
> -		errno = -ERANGE;
> +		errno = ERANGE;
>  		return INT32_MIN;
>  	}
>  	return i;
> @@ -91,7 +91,7 @@ cvt_s16(
>  	if (errno)
>  		return i;
>  	if (i > INT16_MAX || i < INT16_MIN) {
> -		errno = -ERANGE;
> +		errno = ERANGE;
>  		return INT16_MIN;
>  	}
>  	return i;
> @@ -123,7 +123,7 @@ cvt_u64(
>  		return i;
>  
>  	/* Not all the input was consumed, return error. */
> -	errno = -ERANGE;
> +	errno = ERANGE;
>  	return UINT64_MAX;
>  }
>  
> @@ -144,7 +144,7 @@ cvt_u32(
>  	if (errno)
>  		return i;
>  	if (i > UINT32_MAX) {
> -		errno = -ERANGE;
> +		errno = ERANGE;
>  		return UINT32_MAX;
>  	}
>  	return i;
> @@ -167,7 +167,7 @@ cvt_u16(
>  	if (errno)
>  		return i;
>  	if (i > UINT16_MAX) {
> -		errno = -ERANGE;
> +		errno = ERANGE;
>  		return UINT16_MAX;
>  	}
>  	return i;
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll
  2019-06-20 16:49 ` [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll Darrick J. Wong
@ 2019-06-20 19:08   ` Eric Sandeen
  2019-06-25 11:02   ` Christoph Hellwig
  1 sibling, 0 replies; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:08 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:49 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> cvt_u64 converts a string to an unsigned 64-bit number, so it should use
> strtoull, not strtoll because we don't want negative numbers here.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  libfrog/convert.c |   10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> 
> diff --git a/libfrog/convert.c b/libfrog/convert.c
> index 62397507..8d4d4077 100644
> --- a/libfrog/convert.c
> +++ b/libfrog/convert.c
> @@ -105,14 +105,14 @@ cvt_s16(
>   */
>  uint64_t
>  cvt_u64(
> -	char		*s,
> -	int		base)
> +	char			*s,
> +	int			base)
>  {
> -	long long	i;
> -	char		*sp;
> +	unsigned long long	i;
> +	char			*sp;
>  
>  	errno = 0;
> -	i = strtoll(s, &sp, base);
> +	i = strtoull(s, &sp, base);
>  	/*
>  	 * If the input would over or underflow, return the clamped
>  	 * value and let the user check errno.  If we went all the
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/12] libfrog: refactor online geometry queries
  2019-06-20 16:49 ` [PATCH 03/12] libfrog: refactor online geometry queries Darrick J. Wong
@ 2019-06-20 19:16   ` Eric Sandeen
  2019-06-20 21:02     ` Darrick J. Wong
  2019-06-25 14:28   ` Christoph Hellwig
  1 sibling, 1 reply; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:16 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:49 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor all the open-coded XFS_IOC_FSGEOMETRY queries into a single
> helper that we can use to standardize behaviors across mixed xfslibs
> versions.  This is the prelude to introducing a new FSGEOMETRY version
> in 5.2 and needing to fix the (relatively few) client programs.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  Makefile            |    1 +
>  fsr/xfs_fsr.c       |   26 ++++----------------------
>  growfs/xfs_growfs.c |   25 +++++++++----------------
>  include/xfrog.h     |   22 ++++++++++++++++++++++
>  io/bmap.c           |    3 ++-
>  io/fsmap.c          |    3 ++-
>  io/open.c           |    3 ++-
>  io/stat.c           |    5 +++--
>  libfrog/fsgeom.c    |   18 ++++++++++++++++++
>  quota/free.c        |    6 +++---
>  repair/xfs_repair.c |    5 +++--
>  rtcp/Makefile       |    3 +++
>  rtcp/xfs_rtcp.c     |    7 ++++---
>  scrub/phase1.c      |    3 ++-
>  spaceman/file.c     |    3 ++-
>  spaceman/info.c     |   25 ++++++++-----------------
>  16 files changed, 88 insertions(+), 70 deletions(-)
>  create mode 100644 include/xfrog.h

Looks good - only nitpick is that the conversion for testing for
the return code is "rval < 0" and others is just "rval" and the conversion
doesn't seem consistent.   I ... guess it doesn't really matter, as we're
returning either 0 or < 0 and never > 0 it just seemed a bit odd...

i.e.

> -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {

vs

> -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
> +	if (xfrog_geometry(ffd, &ngeo)) {

should we pick one?  "< 0" seems to imply that it could return > 0 and
be ok, which isn't the case, so I'd go for the 2nd type.

> 
> diff --git a/Makefile b/Makefile
> index 9204bed8..0edc2700 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -107,6 +107,7 @@ copy: libxlog
>  mkfs: libxcmd
>  spaceman: libxcmd
>  scrub: libhandle libxcmd
> +rtcp: libfrog
>  
>  ifeq ($(HAVE_BUILDDEFS), yes)
>  include $(BUILDRULES)
> diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
> index fef6262c..0bfecf37 100644
> --- a/fsr/xfs_fsr.c
> +++ b/fsr/xfs_fsr.c
> @@ -11,6 +11,7 @@
>  #include "xfs_bmap_btree.h"
>  #include "xfs_attr_sf.h"
>  #include "path.h"
> +#include "xfrog.h"
>  
>  #include <fcntl.h>
>  #include <errno.h>
> @@ -83,9 +84,8 @@ int cmp(const void *, const void *);
>  static void tmp_init(char *mnt);
>  static char * tmp_next(char *mnt);
>  static void tmp_close(char *mnt);
> -int xfs_getgeom(int , xfs_fsop_geom_v1_t * );
>  
> -static xfs_fsop_geom_v1_t fsgeom;	/* geometry of active mounted system */
> +static struct xfs_fsop_geom fsgeom;	/* geometry of active mounted system */
>  
>  #define NMOUNT 64
>  static int numfs;
> @@ -102,12 +102,6 @@ static int	nfrags = 0;	/* Debug option: Coerse into specific number
>  				 * of extents */
>  static int	openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT;
>  
> -static int
> -xfs_fsgeometry(int fd, xfs_fsop_geom_v1_t *geom)
> -{
> -    return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, geom);
> -}
> -
>  static int
>  xfs_bulkstat_single(int fd, xfs_ino_t *lastip, xfs_bstat_t *ubuffer)
>  {
> @@ -630,7 +624,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
>  		return -1;
>  	}
>  
> -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
>  		fsrprintf(_("Skipping %s: could not get XFS geometry\n"),
>  			  mntdir);
>  		close(fsfd);
> @@ -772,7 +766,7 @@ fsrfile(char *fname, xfs_ino_t ino)
>  	}
>  
>  	/* Get the fs geometry */
> -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
>  		fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
>  		goto out;
>  	}
> @@ -1612,18 +1606,6 @@ getnextents(int fd)
>  	return(nextents);
>  }
>  
> -/*
> - * Get the fs geometry
> - */
> -int
> -xfs_getgeom(int fd, xfs_fsop_geom_v1_t * fsgeom)
> -{
> -	if (xfs_fsgeometry(fd, fsgeom) < 0) {
> -		return -1;
> -	}
> -	return 0;
> -}
> -
>  /*
>   * Get xfs realtime space information
>   */
> diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c
> index 20089d2b..28dd6d84 100644
> --- a/growfs/xfs_growfs.c
> +++ b/growfs/xfs_growfs.c
> @@ -7,6 +7,7 @@
>  #include "libxfs.h"
>  #include "path.h"
>  #include "fsgeom.h"
> +#include "xfrog.h"
>  
>  static void
>  usage(void)
> @@ -165,22 +166,14 @@ main(int argc, char **argv)
>  	}
>  
>  	/* get the current filesystem size & geometry */
> -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY, &geo) < 0) {
> -		/*
> -		 * OK, new xfsctl barfed - back off and try earlier version
> -		 * as we're probably running an older kernel version.
> -		 * Only field added in the v2 geometry xfsctl is "logsunit"
> -		 * so we'll zero that out for later display (as zero).
> -		 */
> -		geo.logsunit = 0;
> -		if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &geo) < 0) {
> -			fprintf(stderr, _(
> -				"%s: cannot determine geometry of filesystem"
> -				" mounted at %s: %s\n"),
> -				progname, fname, strerror(errno));
> -			exit(1);
> -		}
> +	if (xfrog_geometry(ffd, &geo)) {
> +		fprintf(stderr, _(
> +			"%s: cannot determine geometry of filesystem"
> +			" mounted at %s: %s\n"),
> +			progname, fname, strerror(errno));
> +		exit(1);
>  	}
> +
>  	isint = geo.logstart > 0;
>  
>  	/*
> @@ -359,7 +352,7 @@ main(int argc, char **argv)
>  		}
>  	}
>  
> -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
> +	if (xfrog_geometry(ffd, &ngeo)) {
>  		fprintf(stderr, _("%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n"),
>  			progname, strerror(errno));
>  		exit(1);
> diff --git a/include/xfrog.h b/include/xfrog.h
> new file mode 100644
> index 00000000..5420b47c
> --- /dev/null
> +++ b/include/xfrog.h
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2000-2002 Silicon Graphics, Inc.
> + * All Rights Reserved.
> + */
> +#ifndef __XFROG_H__
> +#define __XFROG_H__
> +
> +/*
> + * XFS Filesystem Random Online Gluecode
> + * =====================================
> + *
> + * These support functions wrap the more complex xfs ioctls so that xfs
> + * utilities can take advantage of them without having to deal with graceful
> + * degradation in the face of new ioctls.  They will also provide higher level
> + * abstractions when possible.
> + */
> +
> +struct xfs_fsop_geom;
> +int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
> +
> +#endif	/* __XFROG_H__ */
> diff --git a/io/bmap.c b/io/bmap.c
> index d408826a..5f0d12ca 100644
> --- a/io/bmap.c
> +++ b/io/bmap.c
> @@ -9,6 +9,7 @@
>  #include "input.h"
>  #include "init.h"
>  #include "io.h"
> +#include "xfrog.h"
>  
>  static cmdinfo_t bmap_cmd;
>  
> @@ -105,7 +106,7 @@ bmap_f(
>  		bmv_iflags &= ~(BMV_IF_PREALLOC|BMV_IF_NO_DMAPI_READ);
>  
>  	if (vflag) {
> -		c = xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo);
> +		c = xfrog_geometry(file->fd, &fsgeo);
>  		if (c < 0) {
>  			fprintf(stderr,
>  				_("%s: can't get geometry [\"%s\"]: %s\n"),
> diff --git a/io/fsmap.c b/io/fsmap.c
> index 477c36fc..d3ff7dea 100644
> --- a/io/fsmap.c
> +++ b/io/fsmap.c
> @@ -9,6 +9,7 @@
>  #include "path.h"
>  #include "io.h"
>  #include "input.h"
> +#include "xfrog.h"
>  
>  static cmdinfo_t	fsmap_cmd;
>  static dev_t		xfs_data_dev;
> @@ -447,7 +448,7 @@ fsmap_f(
>  	}
>  
>  	if (vflag) {
> -		c = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &fsgeo);
> +		c = xfrog_geometry(file->fd, &fsgeo);
>  		if (c < 0) {
>  			fprintf(stderr,
>  				_("%s: can't get geometry [\"%s\"]: %s\n"),
> diff --git a/io/open.c b/io/open.c
> index c7f5248a..997df119 100644
> --- a/io/open.c
> +++ b/io/open.c
> @@ -9,6 +9,7 @@
>  #include "init.h"
>  #include "io.h"
>  #include "libxfs.h"
> +#include "xfrog.h"
>  
>  #ifndef __O_TMPFILE
>  #if defined __alpha__
> @@ -118,7 +119,7 @@ openfile(
>  	if (flags & IO_PATH) {
>  		/* Can't call ioctl() on O_PATH fds */
>  		memset(geom, 0, sizeof(*geom));
> -	} else if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
> +	} else if (xfrog_geometry(fd, geom)) {
>  		perror("XFS_IOC_FSGEOMETRY");
>  		close(fd);
>  		return -1;
> diff --git a/io/stat.c b/io/stat.c
> index 37c0b2e8..26b4eb68 100644
> --- a/io/stat.c
> +++ b/io/stat.c
> @@ -12,6 +12,7 @@
>  #include "io.h"
>  #include "statx.h"
>  #include "libxfs.h"
> +#include "xfrog.h"
>  
>  #include <fcntl.h>
>  
> @@ -194,8 +195,8 @@ statfs_f(
>  	}
>  	if (file->flags & IO_FOREIGN)
>  		return 0;
> -	if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
> -		perror("XFS_IOC_FSGEOMETRY_V1");
> +	if (xfrog_geometry(file->fd, &fsgeo)) {
> +		perror("XFS_IOC_FSGEOMETRY");
>  	} else {
>  		printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
>  		printf(_("geom.agcount = %u\n"), fsgeo.agcount);
> diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
> index 8879d161..a6dab3a8 100644
> --- a/libfrog/fsgeom.c
> +++ b/libfrog/fsgeom.c
> @@ -4,6 +4,7 @@
>   */
>  #include "libxfs.h"
>  #include "fsgeom.h"
> +#include "xfrog.h"
>  
>  void
>  xfs_report_geom(
> @@ -67,3 +68,20 @@ xfs_report_geom(
>  		geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks,
>  			(unsigned long long)geo->rtextents);
>  }
> +
> +/* Try to obtain the xfs geometry. */
> +int
> +xfrog_geometry(
> +	int			fd,
> +	struct xfs_fsop_geom	*fsgeo)
> +{
> +	int			ret;
> +
> +	memset(fsgeo, 0, sizeof(*fsgeo));
> +
> +	ret = ioctl(fd, XFS_IOC_FSGEOMETRY, fsgeo);
> +	if (!ret)
> +		return 0;
> +
> +	return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
> +}
> diff --git a/quota/free.c b/quota/free.c
> index 1d13006e..f47001bf 100644
> --- a/quota/free.c
> +++ b/quota/free.c
> @@ -8,6 +8,7 @@
>  #include "command.h"
>  #include "init.h"
>  #include "quota.h"
> +#include "xfrog.h"
>  
>  static cmdinfo_t free_cmd;
>  
> @@ -67,9 +68,8 @@ mount_free_space_data(
>  	}
>  
>  	if (!(mount->fs_flags & FS_FOREIGN)) {
> -		if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSGEOMETRY_V1,
> -							&fsgeo)) < 0) {
> -			perror("XFS_IOC_FSGEOMETRY_V1");
> +		if (xfrog_geometry(fd, &fsgeo)) {
> +			perror("XFS_IOC_FSGEOMETRY");
>  			close(fd);
>  			return 0;
>  		}
> diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
> index 9657503f..e6717d3c 100644
> --- a/repair/xfs_repair.c
> +++ b/repair/xfs_repair.c
> @@ -22,6 +22,7 @@
>  #include "dinode.h"
>  #include "slab.h"
>  #include "rmap.h"
> +#include "xfrog.h"
>  
>  /*
>   * option tables for getsubopt calls
> @@ -636,11 +637,11 @@ check_fs_vs_host_sectsize(
>  {
>  	int	fd;
>  	long	old_flags;
> -	struct xfs_fsop_geom_v1 geom = { 0 };
> +	struct xfs_fsop_geom	geom = { 0 };
>  
>  	fd = libxfs_device_to_fd(x.ddev);
>  
> -	if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) {
> +	if (xfrog_geometry(fd, &geom)) {
>  		do_log(_("Cannot get host filesystem geometry.\n"
>  	"Repair may fail if there is a sector size mismatch between\n"
>  	"the image and the host filesystem.\n"));
> diff --git a/rtcp/Makefile b/rtcp/Makefile
> index 808b5378..264b4f27 100644
> --- a/rtcp/Makefile
> +++ b/rtcp/Makefile
> @@ -9,6 +9,9 @@ LTCOMMAND = xfs_rtcp
>  CFILES = xfs_rtcp.c
>  LLDFLAGS = -static
>  
> +LLDLIBS = $(LIBFROG)
> +LTDEPENDENCIES = $(LIBFROG)
> +
>  default: depend $(LTCOMMAND)
>  
>  include $(BUILDRULES)
> diff --git a/rtcp/xfs_rtcp.c b/rtcp/xfs_rtcp.c
> index f928a86a..0b37ee89 100644
> --- a/rtcp/xfs_rtcp.c
> +++ b/rtcp/xfs_rtcp.c
> @@ -5,6 +5,7 @@
>   */
>  
>  #include "libxfs.h"
> +#include "xfrog.h"
>  
>  int rtcp(char *, char *, int);
>  int xfsrtextsize(char *path);
> @@ -368,8 +369,8 @@ rtcp( char *source, char *target, int fextsize)
>  int
>  xfsrtextsize( char *path)
>  {
> -	int fd, rval, rtextsize;
> -	xfs_fsop_geom_v1_t geo;
> +	struct xfs_fsop_geom	geo;
> +	int			fd, rval, rtextsize;
>  
>  	fd = open( path, O_RDONLY );
>  	if ( fd < 0 ) {
> @@ -377,7 +378,7 @@ xfsrtextsize( char *path)
>  			progname, path, strerror(errno));
>  		return -1;
>  	}
> -	rval = xfsctl( path, fd, XFS_IOC_FSGEOMETRY_V1, &geo );
> +	rval = xfrog_geometry(fd, &geo);
>  	close(fd);
>  	if ( rval < 0 )
>  		return -1;
> diff --git a/scrub/phase1.c b/scrub/phase1.c
> index 04a5f4a9..5ab2a4fe 100644
> --- a/scrub/phase1.c
> +++ b/scrub/phase1.c
> @@ -26,6 +26,7 @@
>  #include "disk.h"
>  #include "scrub.h"
>  #include "repair.h"
> +#include "xfrog.h"
>  
>  /* Phase 1: Find filesystem geometry (and clean up after) */
>  
> @@ -129,7 +130,7 @@ _("Does not appear to be an XFS filesystem!"));
>  	}
>  
>  	/* Retrieve XFS geometry. */
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_FSGEOMETRY, &ctx->geo);
> +	error = xfrog_geometry(ctx->mnt_fd, &ctx->geo);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
> diff --git a/spaceman/file.c b/spaceman/file.c
> index 7e33e07e..9e983d79 100644
> --- a/spaceman/file.c
> +++ b/spaceman/file.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include "libxfs.h"
> +#include "xfrog.h"
>  #include <sys/mman.h>
>  #include "command.h"
>  #include "input.h"
> @@ -56,7 +57,7 @@ openfile(
>  		return -1;
>  	}
>  
> -	if (ioctl(fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
> +	if (xfrog_geometry(fd, geom)) {
>  		if (errno == ENOTTY)
>  			fprintf(stderr,
>  _("%s: Not on a mounted XFS filesystem.\n"),
> diff --git a/spaceman/info.c b/spaceman/info.c
> index 01d0744a..e4dedee2 100644
> --- a/spaceman/info.c
> +++ b/spaceman/info.c
> @@ -4,6 +4,7 @@
>   * Author: Darrick J. Wong <darrick.wong@oracle.com>
>   */
>  #include "libxfs.h"
> +#include "xfrog.h"
>  #include "command.h"
>  #include "init.h"
>  #include "path.h"
> @@ -37,24 +38,14 @@ info_f(
>  	}
>  
>  	/* get the current filesystem size & geometry */
> -	error = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &geo);
> +	error = xfrog_geometry(file->fd, &geo);
>  	if (error) {
> -		/*
> -		 * OK, new xfsctl barfed - back off and try earlier version
> -		 * as we're probably running an older kernel version.
> -		 * Only field added in the v2 geometry xfsctl is "logsunit"
> -		 * so we'll zero that out for later display (as zero).
> -		 */
> -		geo.logsunit = 0;
> -		error = ioctl(file->fd, XFS_IOC_FSGEOMETRY_V1, &geo);
> -		if (error) {
> -			fprintf(stderr, _(
> -				"%s: cannot determine geometry of filesystem"
> -				" mounted at %s: %s\n"),
> -				progname, file->name, strerror(errno));
> -			exitcode = 1;
> -			return 0;
> -		}
> +		fprintf(stderr, _(
> +			"%s: cannot determine geometry of filesystem"
> +			" mounted at %s: %s\n"),
> +			progname, file->name, strerror(errno));
> +		exitcode = 1;
> +		return 0;
>  	}
>  
>  	xfs_report_geom(&geo, file->fs_path.fs_name, file->fs_path.fs_log,
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 04/12] libfrog: introduce xfrog context
  2019-06-20 16:49 ` [PATCH 04/12] libfrog: introduce xfrog context Darrick J. Wong
@ 2019-06-20 19:40   ` Eric Sandeen
  0 siblings, 0 replies; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:49 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Introduce a new "xfrog" context structure where we can store a file
> descriptor and all the runtime fs context (geometry, which ioctls work,
> etc.) that goes with it.  We're going to create wrappers for the
> bulkstat and inumbers ioctls in subsequent patches; and when we
> introduce the v5 bulkstat/inumbers ioctls we'll need all that context to
> downgrade gracefully on old kernels.  Start the transition by adopting
> xfrog natively in scrub.

Hm, I've tolerated the frog thing with good humor, but "froggie" is ...
getting to be a bit too much for me.  I understand that's totally
subjective ...

It's just that it has no mnemonic meaning at this point.

Funny Random Other Gunk ?
Filesystem Random Online Gluecode?

I'm all for having some fun in the code but it's getting to the point
where it's interfering w/ my ability to read the code and know what's
going on.  Naming the library "libfrog" didn't really get in the way,
but trying to read past "froggie->fsgeom" just isn't happening for me
without some mental jarring.

Can we give this new thing (structure & variables) a descriptive name
for readability and maintainability's sake?

"xcontext" or "fdcontext" is boring, but far more descriptive than
"froggie" IMHO.  Sorry.  :(


> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  include/xfrog.h    |   20 ++++++++++++++++++++
>  libfrog/fsgeom.c   |   25 +++++++++++++++++++++++++
>  scrub/fscounters.c |   22 ++++++++++++----------
>  scrub/inodes.c     |   10 +++++-----
>  scrub/phase1.c     |   41 ++++++++++++++++++++---------------------
>  scrub/phase2.c     |    2 +-
>  scrub/phase3.c     |    4 ++--
>  scrub/phase4.c     |    8 ++++----
>  scrub/phase5.c     |    2 +-
>  scrub/phase6.c     |    6 +++---
>  scrub/phase7.c     |    2 +-
>  scrub/repair.c     |    4 ++--
>  scrub/scrub.c      |   12 ++++++------
>  scrub/spacemap.c   |   12 ++++++------
>  scrub/vfs.c        |    2 +-
>  scrub/xfs_scrub.h  |    7 ++++---
>  16 files changed, 113 insertions(+), 66 deletions(-)
> 
> 
> diff --git a/include/xfrog.h b/include/xfrog.h
> index 5420b47c..e450ee1d 100644
> --- a/include/xfrog.h
> +++ b/include/xfrog.h
> @@ -19,4 +19,24 @@
>  struct xfs_fsop_geom;
>  int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
>  
> +/*
> + * Structure for recording whatever observations we want about the level of
> + * xfs runtime support for this fd.  Right now we only store the fd and fs
> + * geometry.
> + */
> +struct xfrog {
> +	/* ioctl file descriptor */
> +	int			fd;
> +
> +	/* filesystem geometry */
> +	struct xfs_fsop_geom	fsgeom;
> +};
> +
> +/* Static initializers */
> +#define XFROG_INIT(_fd)		{ .fd = (_fd), }
> +#define XFROG_INIT_EMPTY	XFROG_INIT(-1)
> +
> +int xfrog_prepare_geometry(struct xfrog *froggie);
> +int xfrog_close(struct xfrog *froggie);
> +
>  #endif	/* __XFROG_H__ */
> diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
> index a6dab3a8..bf76b520 100644
> --- a/libfrog/fsgeom.c
> +++ b/libfrog/fsgeom.c
> @@ -85,3 +85,28 @@ xfrog_geometry(
>  
>  	return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
>  }
> +
> +/*
> + * Prepare xfrog structure for future ioctl operations by computing the xfs
> + * geometry for @froggie->fd.
> + */
> +int
> +xfrog_prepare_geometry(
> +	struct xfrog		*froggie)
> +{
> +	return xfrog_geometry(froggie->fd, &froggie->fsgeom);
> +}
> +
> +/* Release any resources associated with this xfrog structure. */
> +int
> +xfrog_close(
> +	struct xfrog		*froggie)
> +{
> +	int			ret = 0;
> +
> +	if (froggie->fd >= 0)
> +		ret = close(froggie->fd);
> +
> +	froggie->fd = -1;
> +	return ret;
> +}
> diff --git a/scrub/fscounters.c b/scrub/fscounters.c
> index 9e93e2a6..f18d0e19 100644
> --- a/scrub/fscounters.c
> +++ b/scrub/fscounters.c
> @@ -57,10 +57,10 @@ xfs_count_inodes_range(
>  	igrpreq.ocount  = &igrplen;
>  
>  	igrp_ino = first_ino;
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
> +	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);
> +		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
>  	}
>  
>  	if (error) {
> @@ -113,7 +113,7 @@ xfs_count_all_inodes(
>  	int			ret;
>  
>  	ci = calloc(1, sizeof(struct xfs_count_inodes) +
> -			(ctx->geo.agcount * sizeof(uint64_t)));
> +			(ctx->mnt.fsgeom.agcount * sizeof(uint64_t)));
>  	if (!ci)
>  		return false;
>  	ci->moveon = true;
> @@ -125,7 +125,7 @@ xfs_count_all_inodes(
>  		str_info(ctx, ctx->mntpoint, _("Could not create workqueue."));
>  		goto out_free;
>  	}
> -	for (agno = 0; agno < ctx->geo.agcount; agno++) {
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
>  		ret = workqueue_add(&wq, xfs_count_ag_inodes, agno, ci);
>  		if (ret) {
>  			moveon = false;
> @@ -136,7 +136,7 @@ _("Could not queue AG %u icount work."), agno);
>  	}
>  	workqueue_destroy(&wq);
>  
> -	for (agno = 0; agno < ctx->geo.agcount; agno++)
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++)
>  		*count += ci->counters[agno];
>  	moveon = ci->moveon;
>  
> @@ -162,14 +162,14 @@ xfs_scan_estimate_blocks(
>  	int				error;
>  
>  	/* Grab the fstatvfs counters, since it has to report accurately. */
> -	error = fstatvfs(ctx->mnt_fd, &sfs);
> +	error = fstatvfs(ctx->mnt.fd, &sfs);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
>  
>  	/* Fetch the filesystem counters. */
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_FSCOUNTS, &fc);
> +	error = ioctl(ctx->mnt.fd, XFS_IOC_FSCOUNTS, &fc);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
> @@ -179,14 +179,16 @@ xfs_scan_estimate_blocks(
>  	 * XFS reserves some blocks to prevent hard ENOSPC, so add those
>  	 * blocks back to the free data counts.
>  	 */
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_GET_RESBLKS, &rb);
> +	error = ioctl(ctx->mnt.fd, XFS_IOC_GET_RESBLKS, &rb);
>  	if (error)
>  		str_errno(ctx, ctx->mntpoint);
>  	sfs.f_bfree += rb.resblks_avail;
>  
> -	*d_blocks = sfs.f_blocks + (ctx->geo.logstart ? ctx->geo.logblocks : 0);
> +	*d_blocks = sfs.f_blocks;
> +	if (ctx->mnt.fsgeom.logstart > 0)
> +		*d_blocks += ctx->mnt.fsgeom.logblocks;
>  	*d_bfree = sfs.f_bfree;
> -	*r_blocks = ctx->geo.rtblocks;
> +	*r_blocks = ctx->mnt.fsgeom.rtblocks;
>  	*r_bfree = fc.freertx;
>  	*f_files = sfs.f_files;
>  	*f_free = sfs.f_ffree;
> diff --git a/scrub/inodes.c b/scrub/inodes.c
> index 442a5978..08f3d847 100644
> --- a/scrub/inodes.c
> +++ b/scrub/inodes.c
> @@ -72,7 +72,7 @@ xfs_iterate_inodes_range_check(
>  		/* Load the one inode. */
>  		oneino = inogrp->xi_startino + i;
>  		onereq.ubuffer = bs;
> -		error = ioctl(ctx->mnt_fd, XFS_IOC_FSBULKSTAT_SINGLE,
> +		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT_SINGLE,
>  				&onereq);
>  		if (error || bs->bs_ino != inogrp->xi_startino + i) {
>  			memset(bs, 0, sizeof(struct xfs_bstat));
> @@ -134,7 +134,7 @@ xfs_iterate_inodes_range(
>  
>  	/* Find the inode chunk & alloc mask */
>  	igrp_ino = first_ino;
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
> +	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
>  	while (!error && igrplen) {
>  		/* Load the inodes. */
>  		ino = inogrp.xi_startino - 1;
> @@ -145,7 +145,7 @@ xfs_iterate_inodes_range(
>  		 */
>  		if (inogrp.xi_alloccount == 0)
>  			goto igrp_retry;
> -		error = ioctl(ctx->mnt_fd, XFS_IOC_FSBULKSTAT, &bulkreq);
> +		error = ioctl(ctx->mnt.fd, XFS_IOC_FSBULKSTAT, &bulkreq);
>  		if (error)
>  			str_info(ctx, descr, "%s", strerror_r(errno,
>  						buf, DESCR_BUFSZ));
> @@ -190,7 +190,7 @@ _("Changed too many times during scan; giving up."));
>  
>  		stale_count = 0;
>  igrp_retry:
> -		error = ioctl(ctx->mnt_fd, XFS_IOC_FSINUMBERS, &igrpreq);
> +		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
>  	}
>  
>  err:
> @@ -260,7 +260,7 @@ xfs_scan_all_inodes(
>  		return false;
>  	}
>  
> -	for (agno = 0; agno < ctx->geo.agcount; agno++) {
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
>  		ret = workqueue_add(&wq, xfs_scan_ag_inodes, agno, &si);
>  		if (ret) {
>  			si.moveon = false;
> diff --git a/scrub/phase1.c b/scrub/phase1.c
> index 5ab2a4fe..c7034527 100644
> --- a/scrub/phase1.c
> +++ b/scrub/phase1.c
> @@ -39,7 +39,7 @@ xfs_shutdown_fs(
>  
>  	flag = XFS_FSOP_GOING_FLAGS_LOGFLUSH;
>  	str_info(ctx, ctx->mntpoint, _("Shutting down filesystem!"));
> -	if (ioctl(ctx->mnt_fd, XFS_IOC_GOINGDOWN, &flag))
> +	if (ioctl(ctx->mnt.fd, XFS_IOC_GOINGDOWN, &flag))
>  		str_errno(ctx, ctx->mntpoint);
>  }
>  
> @@ -60,11 +60,9 @@ xfs_cleanup_fs(
>  	if (ctx->datadev)
>  		disk_close(ctx->datadev);
>  	fshandle_destroy();
> -	if (ctx->mnt_fd >= 0) {
> -		error = close(ctx->mnt_fd);
> -		if (error)
> -			str_errno(ctx, _("closing mountpoint fd"));
> -	}
> +	error = xfrog_close(&ctx->mnt);
> +	if (error)
> +		str_errno(ctx, _("closing mountpoint fd"));
>  	fs_table_destroy();
>  
>  	return true;
> @@ -86,8 +84,8 @@ xfs_setup_fs(
>  	 * CAP_SYS_ADMIN, which we probably need to do anything fancy
>  	 * with the (XFS driver) kernel.
>  	 */
> -	ctx->mnt_fd = open(ctx->mntpoint, O_RDONLY | O_NOATIME | O_DIRECTORY);
> -	if (ctx->mnt_fd < 0) {
> +	ctx->mnt.fd = open(ctx->mntpoint, O_RDONLY | O_NOATIME | O_DIRECTORY);
> +	if (ctx->mnt.fd < 0) {
>  		if (errno == EPERM)
>  			str_info(ctx, ctx->mntpoint,
>  _("Must be root to run scrub."));
> @@ -96,23 +94,23 @@ _("Must be root to run scrub."));
>  		return false;
>  	}
>  
> -	error = fstat(ctx->mnt_fd, &ctx->mnt_sb);
> +	error = fstat(ctx->mnt.fd, &ctx->mnt_sb);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
> -	error = fstatvfs(ctx->mnt_fd, &ctx->mnt_sv);
> +	error = fstatvfs(ctx->mnt.fd, &ctx->mnt_sv);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
> -	error = fstatfs(ctx->mnt_fd, &ctx->mnt_sf);
> +	error = fstatfs(ctx->mnt.fd, &ctx->mnt_sf);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
>  
> -	if (!platform_test_xfs_fd(ctx->mnt_fd)) {
> +	if (!platform_test_xfs_fd(ctx->mnt.fd)) {
>  		str_info(ctx, ctx->mntpoint,
>  _("Does not appear to be an XFS filesystem!"));
>  		return false;
> @@ -123,27 +121,28 @@ _("Does not appear to be an XFS filesystem!"));
>  	 * This seems to reduce the incidence of stale file handle
>  	 * errors when we open things by handle.
>  	 */
> -	error = syncfs(ctx->mnt_fd);
> +	error = syncfs(ctx->mnt.fd);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
>  
> -	/* Retrieve XFS geometry. */
> -	error = xfrog_geometry(ctx->mnt_fd, &ctx->geo);
> +	/* Set up xfrog and compute XFS geometry. */
> +	error = xfrog_prepare_geometry(&ctx->mnt);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
>  	}
>  
> -	if (!xfs_action_lists_alloc(ctx->geo.agcount, &ctx->action_lists)) {
> +	if (!xfs_action_lists_alloc(ctx->mnt.fsgeom.agcount,
> +				&ctx->action_lists)) {
>  		str_error(ctx, ctx->mntpoint, _("Not enough memory."));
>  		return false;
>  	}
>  
> -	ctx->agblklog = log2_roundup(ctx->geo.agblocks);
> -	ctx->blocklog = highbit32(ctx->geo.blocksize);
> -	ctx->inodelog = highbit32(ctx->geo.inodesize);
> +	ctx->agblklog = log2_roundup(ctx->mnt.fsgeom.agblocks);
> +	ctx->blocklog = highbit32(ctx->mnt.fsgeom.blocksize);
> +	ctx->inodelog = highbit32(ctx->mnt.fsgeom.inodesize);
>  	ctx->inopblog = ctx->blocklog - ctx->inodelog;
>  
>  	error = path_to_fshandle(ctx->mntpoint, &ctx->fshandle,
> @@ -171,12 +170,12 @@ _("Kernel metadata repair facility is not available.  Use -n to scrub."));
>  	}
>  
>  	/* Did we find the log and rt devices, if they're present? */
> -	if (ctx->geo.logstart == 0 && ctx->fsinfo.fs_log == NULL) {
> +	if (ctx->mnt.fsgeom.logstart == 0 && ctx->fsinfo.fs_log == NULL) {
>  		str_info(ctx, ctx->mntpoint,
>  _("Unable to find log device path."));
>  		return false;
>  	}
> -	if (ctx->geo.rtblocks && ctx->fsinfo.fs_rt == NULL) {
> +	if (ctx->mnt.fsgeom.rtblocks && ctx->fsinfo.fs_rt == NULL) {
>  		str_info(ctx, ctx->mntpoint,
>  _("Unable to find realtime device path."));
>  		return false;
> diff --git a/scrub/phase2.c b/scrub/phase2.c
> index 653f666c..a80da7fd 100644
> --- a/scrub/phase2.c
> +++ b/scrub/phase2.c
> @@ -141,7 +141,7 @@ xfs_scan_metadata(
>  	if (!moveon)
>  		goto out;
>  
> -	for (agno = 0; moveon && agno < ctx->geo.agcount; agno++) {
> +	for (agno = 0; moveon && agno < ctx->mnt.fsgeom.agcount; agno++) {
>  		ret = workqueue_add(&wq, xfs_scan_ag_metadata, agno, &moveon);
>  		if (ret) {
>  			moveon = false;
> diff --git a/scrub/phase3.c b/scrub/phase3.c
> index 4963d675..a42d8213 100644
> --- a/scrub/phase3.c
> +++ b/scrub/phase3.c
> @@ -33,7 +33,7 @@ xfs_scrub_fd(
>  	struct xfs_bstat	*bs,
>  	struct xfs_action_list	*alist)
>  {
> -	return fn(ctx, bs->bs_ino, bs->bs_gen, ctx->mnt_fd, alist);
> +	return fn(ctx, bs->bs_ino, bs->bs_gen, ctx->mnt.fd, alist);
>  }
>  
>  struct scrub_inode_ctx {
> @@ -115,7 +115,7 @@ xfs_scrub_inode(
>  	if (S_ISLNK(bstat->bs_mode)) {
>  		/* Check symlink contents. */
>  		moveon = xfs_scrub_symlink(ctx, bstat->bs_ino,
> -				bstat->bs_gen, ctx->mnt_fd, &alist);
> +				bstat->bs_gen, ctx->mnt.fd, &alist);
>  	} else if (S_ISDIR(bstat->bs_mode)) {
>  		/* Check the directory entries. */
>  		moveon = xfs_scrub_fd(ctx, xfs_scrub_dir, bstat, &alist);
> diff --git a/scrub/phase4.c b/scrub/phase4.c
> index 79248326..49f00723 100644
> --- a/scrub/phase4.c
> +++ b/scrub/phase4.c
> @@ -40,7 +40,7 @@ xfs_repair_ag(
>  
>  	/* Repair anything broken until we fail to make progress. */
>  	do {
> -		moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist, flags);
> +		moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist, flags);
>  		if (!moveon) {
>  			*pmoveon = false;
>  			return;
> @@ -56,7 +56,7 @@ xfs_repair_ag(
>  
>  	/* Try once more, but this time complain if we can't fix things. */
>  	flags |= ALP_COMPLAIN_IF_UNFIXED;
> -	moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist, flags);
> +	moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist, flags);
>  	if (!moveon)
>  		*pmoveon = false;
>  }
> @@ -77,7 +77,7 @@ xfs_process_action_items(
>  		str_error(ctx, ctx->mntpoint, _("Could not create workqueue."));
>  		return false;
>  	}
> -	for (agno = 0; agno < ctx->geo.agcount; agno++) {
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
>  		if (xfs_action_list_length(&ctx->action_lists[agno]) > 0) {
>  			ret = workqueue_add(&wq, xfs_repair_ag, agno, &moveon);
>  			if (ret) {
> @@ -121,7 +121,7 @@ xfs_estimate_repair_work(
>  	xfs_agnumber_t		agno;
>  	size_t			need_fixing = 0;
>  
> -	for (agno = 0; agno < ctx->geo.agcount; agno++)
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++)
>  		need_fixing += xfs_action_list_length(&ctx->action_lists[agno]);
>  	need_fixing++;
>  	*items = need_fixing;
> diff --git a/scrub/phase5.c b/scrub/phase5.c
> index 1743119d..748885d4 100644
> --- a/scrub/phase5.c
> +++ b/scrub/phase5.c
> @@ -306,7 +306,7 @@ xfs_scrub_fs_label(
>  		return false;
>  
>  	/* Retrieve label; quietly bail if we don't support that. */
> -	error = ioctl(ctx->mnt_fd, FS_IOC_GETFSLABEL, &label);
> +	error = ioctl(ctx->mnt.fd, FS_IOC_GETFSLABEL, &label);
>  	if (error) {
>  		if (errno != EOPNOTSUPP && errno != ENOTTY) {
>  			moveon = false;
> diff --git a/scrub/phase6.c b/scrub/phase6.c
> index 66e6451c..e5a0b3c1 100644
> --- a/scrub/phase6.c
> +++ b/scrub/phase6.c
> @@ -468,7 +468,7 @@ xfs_scan_blocks(
>  	}
>  
>  	vs.rvp_data = read_verify_pool_init(ctx, ctx->datadev,
> -			ctx->geo.blocksize, xfs_check_rmap_ioerr,
> +			ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
>  			scrub_nproc(ctx));
>  	if (!vs.rvp_data) {
>  		str_info(ctx, ctx->mntpoint,
> @@ -477,7 +477,7 @@ _("Could not create data device media verifier."));
>  	}
>  	if (ctx->logdev) {
>  		vs.rvp_log = read_verify_pool_init(ctx, ctx->logdev,
> -				ctx->geo.blocksize, xfs_check_rmap_ioerr,
> +				ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
>  				scrub_nproc(ctx));
>  		if (!vs.rvp_log) {
>  			str_info(ctx, ctx->mntpoint,
> @@ -487,7 +487,7 @@ _("Could not create data device media verifier."));
>  	}
>  	if (ctx->rtdev) {
>  		vs.rvp_realtime = read_verify_pool_init(ctx, ctx->rtdev,
> -				ctx->geo.blocksize, xfs_check_rmap_ioerr,
> +				ctx->mnt.fsgeom.blocksize, xfs_check_rmap_ioerr,
>  				scrub_nproc(ctx));
>  		if (!vs.rvp_realtime) {
>  			str_info(ctx, ctx->mntpoint,
> diff --git a/scrub/phase7.c b/scrub/phase7.c
> index 0c3202e4..13959ca8 100644
> --- a/scrub/phase7.c
> +++ b/scrub/phase7.c
> @@ -111,7 +111,7 @@ xfs_scan_summary(
>  	int			error;
>  
>  	/* Flush everything out to disk before we start counting. */
> -	error = syncfs(ctx->mnt_fd);
> +	error = syncfs(ctx->mnt.fd);
>  	if (error) {
>  		str_errno(ctx, ctx->mntpoint);
>  		return false;
> diff --git a/scrub/repair.c b/scrub/repair.c
> index 4ed3c09a..45450d8c 100644
> --- a/scrub/repair.c
> +++ b/scrub/repair.c
> @@ -262,7 +262,7 @@ xfs_action_list_defer(
>  	xfs_agnumber_t			agno,
>  	struct xfs_action_list		*alist)
>  {
> -	ASSERT(agno < ctx->geo.agcount);
> +	ASSERT(agno < ctx->mnt.fsgeom.agcount);
>  
>  	xfs_action_list_splice(&ctx->action_lists[agno], alist);
>  }
> @@ -276,7 +276,7 @@ xfs_action_list_process_or_defer(
>  {
>  	bool				moveon;
>  
> -	moveon = xfs_action_list_process(ctx, ctx->mnt_fd, alist,
> +	moveon = xfs_action_list_process(ctx, ctx->mnt.fd, alist,
>  			ALP_REPAIR_ONLY | ALP_NOPROGRESS);
>  	if (!moveon)
>  		return moveon;
> diff --git a/scrub/scrub.c b/scrub/scrub.c
> index 0f0c9639..136ed529 100644
> --- a/scrub/scrub.c
> +++ b/scrub/scrub.c
> @@ -363,7 +363,7 @@ xfs_scrub_metadata(
>  		background_sleep();
>  
>  		/* Check the item. */
> -		fix = xfs_check_metadata(ctx, ctx->mnt_fd, &meta, false);
> +		fix = xfs_check_metadata(ctx, ctx->mnt.fd, &meta, false);
>  		progress_add(1);
>  		switch (fix) {
>  		case CHECK_ABORT:
> @@ -399,7 +399,7 @@ xfs_scrub_primary_super(
>  	enum check_outcome		fix;
>  
>  	/* Check the item. */
> -	fix = xfs_check_metadata(ctx, ctx->mnt_fd, &meta, false);
> +	fix = xfs_check_metadata(ctx, ctx->mnt.fd, &meta, false);
>  	switch (fix) {
>  	case CHECK_ABORT:
>  		return false;
> @@ -460,7 +460,7 @@ xfs_scrub_estimate_ag_work(
>  		switch (sc->type) {
>  		case ST_AGHEADER:
>  		case ST_PERAG:
> -			estimate += ctx->geo.agcount;
> +			estimate += ctx->mnt.fsgeom.agcount;
>  			break;
>  		case ST_FS:
>  			estimate++;
> @@ -605,9 +605,9 @@ __xfs_scrub_test(
>  	if (debug_tweak_on("XFS_SCRUB_NO_KERNEL"))
>  		return false;
>  	if (debug_tweak_on("XFS_SCRUB_FORCE_REPAIR") && !injected) {
> -		inject.fd = ctx->mnt_fd;
> +		inject.fd = ctx->mnt.fd;
>  		inject.errtag = XFS_ERRTAG_FORCE_SCRUB_REPAIR;
> -		error = ioctl(ctx->mnt_fd, XFS_IOC_ERROR_INJECTION, &inject);
> +		error = ioctl(ctx->mnt.fd, XFS_IOC_ERROR_INJECTION, &inject);
>  		if (error == 0)
>  			injected = true;
>  	}
> @@ -615,7 +615,7 @@ __xfs_scrub_test(
>  	meta.sm_type = type;
>  	if (repair)
>  		meta.sm_flags |= XFS_SCRUB_IFLAG_REPAIR;
> -	error = ioctl(ctx->mnt_fd, XFS_IOC_SCRUB_METADATA, &meta);
> +	error = ioctl(ctx->mnt.fd, XFS_IOC_SCRUB_METADATA, &meta);
>  	if (!error)
>  		return true;
>  	switch (errno) {
> diff --git a/scrub/spacemap.c b/scrub/spacemap.c
> index d547a041..c3621a3a 100644
> --- a/scrub/spacemap.c
> +++ b/scrub/spacemap.c
> @@ -56,7 +56,7 @@ xfs_iterate_fsmap(
>  	memcpy(head->fmh_keys, keys, sizeof(struct fsmap) * 2);
>  	head->fmh_count = FSMAP_NR;
>  
> -	while ((error = ioctl(ctx->mnt_fd, FS_IOC_GETFSMAP, head)) == 0) {
> +	while ((error = ioctl(ctx->mnt.fd, FS_IOC_GETFSMAP, head)) == 0) {
>  		for (i = 0, p = head->fmh_recs;
>  		     i < head->fmh_entries;
>  		     i++, p++) {
> @@ -107,8 +107,8 @@ xfs_scan_ag_blocks(
>  	off64_t			bperag;
>  	bool			moveon;
>  
> -	bperag = (off64_t)ctx->geo.agblocks *
> -		 (off64_t)ctx->geo.blocksize;
> +	bperag = (off64_t)ctx->mnt.fsgeom.agblocks *
> +		 (off64_t)ctx->mnt.fsgeom.blocksize;
>  
>  	snprintf(descr, DESCR_BUFSZ, _("dev %d:%d AG %u fsmap"),
>  				major(ctx->fsinfo.fs_datadev),
> @@ -205,7 +205,7 @@ xfs_scan_all_spacemaps(
>  	}
>  	if (ctx->fsinfo.fs_rt) {
>  		ret = workqueue_add(&wq, xfs_scan_rt_blocks,
> -				ctx->geo.agcount + 1, &sbx);
> +				ctx->mnt.fsgeom.agcount + 1, &sbx);
>  		if (ret) {
>  			sbx.moveon = false;
>  			str_info(ctx, ctx->mntpoint,
> @@ -215,7 +215,7 @@ _("Could not queue rtdev fsmap work."));
>  	}
>  	if (ctx->fsinfo.fs_log) {
>  		ret = workqueue_add(&wq, xfs_scan_log_blocks,
> -				ctx->geo.agcount + 2, &sbx);
> +				ctx->mnt.fsgeom.agcount + 2, &sbx);
>  		if (ret) {
>  			sbx.moveon = false;
>  			str_info(ctx, ctx->mntpoint,
> @@ -223,7 +223,7 @@ _("Could not queue logdev fsmap work."));
>  			goto out;
>  		}
>  	}
> -	for (agno = 0; agno < ctx->geo.agcount; agno++) {
> +	for (agno = 0; agno < ctx->mnt.fsgeom.agcount; agno++) {
>  		ret = workqueue_add(&wq, xfs_scan_ag_blocks, agno, &sbx);
>  		if (ret) {
>  			sbx.moveon = false;
> diff --git a/scrub/vfs.c b/scrub/vfs.c
> index 8bcc4e79..7b0b5bcd 100644
> --- a/scrub/vfs.c
> +++ b/scrub/vfs.c
> @@ -232,7 +232,7 @@ fstrim(
>  	int			error;
>  
>  	range.len = ULLONG_MAX;
> -	error = ioctl(ctx->mnt_fd, FITRIM, &range);
> +	error = ioctl(ctx->mnt.fd, FITRIM, &range);
>  	if (error && errno != EOPNOTSUPP && errno != ENOTTY)
>  		perror(_("fstrim"));
>  }
> diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
> index a459e4b5..3eb7ed79 100644
> --- a/scrub/xfs_scrub.h
> +++ b/scrub/xfs_scrub.h
> @@ -6,6 +6,8 @@
>  #ifndef XFS_SCRUB_XFS_SCRUB_H_
>  #define XFS_SCRUB_XFS_SCRUB_H_
>  
> +#include <xfrog.h>
> +
>  extern char *progname;
>  
>  #define _PATH_PROC_MOUNTS	"/proc/mounts"
> @@ -53,14 +55,13 @@ struct scrub_ctx {
>  	/* How does the user want us to react to errors? */
>  	enum error_action	error_action;
>  
> -	/* fd to filesystem mount point */
> -	int			mnt_fd;
> +	/* xfrog context for the mount point */
> +	struct xfrog		mnt;
>  
>  	/* Number of threads for metadata scrubbing */
>  	unsigned int		nr_io_threads;
>  
>  	/* XFS specific geometry */
> -	struct xfs_fsop_geom	geo;
>  	struct fs_path		fsinfo;
>  	unsigned int		agblklog;
>  	unsigned int		blocklog;
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 09/12] mkfs: validate start and end of aligned logs
  2019-06-20 16:50 ` [PATCH 09/12] mkfs: validate start and end of aligned logs Darrick J. Wong
@ 2019-06-20 19:46   ` Eric Sandeen
  0 siblings, 0 replies; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:46 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:50 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Validate that the start and end of the log stay within a single AG if
> we adjust either end to align to stripe units.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  mkfs/xfs_mkfs.c |   15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> 
> diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
> index ddb25ecc..468b8fde 100644
> --- a/mkfs/xfs_mkfs.c
> +++ b/mkfs/xfs_mkfs.c
> @@ -3033,15 +3033,28 @@ align_internal_log(
>  	struct xfs_mount	*mp,
>  	int			sunit)
>  {
> +	uint64_t		logend;
> +
>  	/* round up log start if necessary */
>  	if ((cfg->logstart % sunit) != 0)
>  		cfg->logstart = ((cfg->logstart + (sunit - 1)) / sunit) * sunit;
>  
> +	/* If our log start overlaps the next AG's metadata, fail. */
> +	if (!xfs_verify_fsbno(mp, cfg->logstart)) {
> +			fprintf(stderr,
> +_("Due to stripe alignment, the internal log start (%lld) cannot be aligned\n"
> +  "within an allocation group.\n"),
> +			(long long) cfg->logstart);
> +		usage();
> +	}
> +
>  	/* round up/down the log size now */
>  	align_log_size(cfg, sunit);
>  
>  	/* check the aligned log still fits in an AG. */
> -	if (cfg->logblocks > cfg->agsize - XFS_FSB_TO_AGBNO(mp, cfg->logstart)) {
> +	logend = cfg->logstart + cfg->logblocks - 1;
> +	if (XFS_FSB_TO_AGNO(mp, cfg->logstart) != XFS_FSB_TO_AGNO(mp, logend) ||
> +	    !xfs_verify_fsbno(mp, logend)) {
>  		fprintf(stderr,
>  _("Due to stripe alignment, the internal log size (%lld) is too large.\n"
>    "Must fit within an allocation group.\n"),
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 10/12] xfs_io: repair_f should use its own name
  2019-06-20 16:50 ` [PATCH 10/12] xfs_io: repair_f should use its own name Darrick J. Wong
@ 2019-06-20 19:52   ` Eric Sandeen
  0 siblings, 0 replies; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:50 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> If the repair command fails, it should tag the error message with its
> own name ("repair").
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Reviewed-by: Eric Sandeen <sandeen@redhat.com>

> ---
>  io/scrub.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> 
> diff --git a/io/scrub.c b/io/scrub.c
> index 2ff1a6af..052497be 100644
> --- a/io/scrub.c
> +++ b/io/scrub.c
> @@ -293,7 +293,7 @@ repair_ioctl(
>  
>  	error = ioctl(fd, XFS_IOC_SCRUB_METADATA, &meta);
>  	if (error)
> -		perror("scrub");
> +		perror("repair");
>  	if (meta.sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
>  		printf(_("Corruption remains.\n"));
>  	if (meta.sm_flags & XFS_SCRUB_OFLAG_PREEN)
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files
  2019-06-20 16:50 ` [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files Darrick J. Wong
@ 2019-06-20 19:53   ` Eric Sandeen
  2019-06-20 19:57     ` Darrick J. Wong
  0 siblings, 1 reply; 26+ messages in thread
From: Eric Sandeen @ 2019-06-20 19:53 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-xfs

On 6/20/19 11:50 AM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Now that we're syncing userspace libxfs/ files with kernel fs/xfs/
> files, teach the diff tool to try fs/xfs/xfs_foo.c if
> fs/xfs/libxfs/xfs_foo.c doesn't exist.

do we really need this or should I just send a patch for the kernel
to move it?

-Eric

> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  tools/libxfs-diff |    1 +
>  1 file changed, 1 insertion(+)
> 
> 
> diff --git a/tools/libxfs-diff b/tools/libxfs-diff
> index fa57c004..c18ad487 100755
> --- a/tools/libxfs-diff
> +++ b/tools/libxfs-diff
> @@ -22,5 +22,6 @@ dir="$(readlink -m "${dir}/..")"
>  
>  for i in libxfs/xfs*.[ch]; do
>  	kfile="${dir}/$i"
> +	test -f "${kfile}" || kfile="$(echo "${kfile}" | sed -e 's|libxfs/||g')"
>  	diff -Naurpw --label "$i" <(sed -e '/#include/d' "$i") --label "${kfile}" <(sed -e '/#include/d' "${kfile}")
>  done
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files
  2019-06-20 19:53   ` Eric Sandeen
@ 2019-06-20 19:57     ` Darrick J. Wong
  0 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 19:57 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Thu, Jun 20, 2019 at 02:53:14PM -0500, Eric Sandeen wrote:
> On 6/20/19 11:50 AM, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Now that we're syncing userspace libxfs/ files with kernel fs/xfs/
> > files, teach the diff tool to try fs/xfs/xfs_foo.c if
> > fs/xfs/libxfs/xfs_foo.c doesn't exist.
> 
> do we really need this or should I just send a patch for the kernel
> to move it?

Nah just send a kernel patch.

--D

> -Eric
> 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  tools/libxfs-diff |    1 +
> >  1 file changed, 1 insertion(+)
> > 
> > 
> > diff --git a/tools/libxfs-diff b/tools/libxfs-diff
> > index fa57c004..c18ad487 100755
> > --- a/tools/libxfs-diff
> > +++ b/tools/libxfs-diff
> > @@ -22,5 +22,6 @@ dir="$(readlink -m "${dir}/..")"
> >  
> >  for i in libxfs/xfs*.[ch]; do
> >  	kfile="${dir}/$i"
> > +	test -f "${kfile}" || kfile="$(echo "${kfile}" | sed -e 's|libxfs/||g')"
> >  	diff -Naurpw --label "$i" <(sed -e '/#include/d' "$i") --label "${kfile}" <(sed -e '/#include/d' "${kfile}")
> >  done
> > 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/12] libfrog: refactor online geometry queries
  2019-06-20 19:16   ` Eric Sandeen
@ 2019-06-20 21:02     ` Darrick J. Wong
  0 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-20 21:02 UTC (permalink / raw)
  To: Eric Sandeen; +Cc: linux-xfs

On Thu, Jun 20, 2019 at 02:16:41PM -0500, Eric Sandeen wrote:
> On 6/20/19 11:49 AM, Darrick J. Wong wrote:
> > From: Darrick J. Wong <darrick.wong@oracle.com>
> > 
> > Refactor all the open-coded XFS_IOC_FSGEOMETRY queries into a single
> > helper that we can use to standardize behaviors across mixed xfslibs
> > versions.  This is the prelude to introducing a new FSGEOMETRY version
> > in 5.2 and needing to fix the (relatively few) client programs.
> > 
> > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > ---
> >  Makefile            |    1 +
> >  fsr/xfs_fsr.c       |   26 ++++----------------------
> >  growfs/xfs_growfs.c |   25 +++++++++----------------
> >  include/xfrog.h     |   22 ++++++++++++++++++++++
> >  io/bmap.c           |    3 ++-
> >  io/fsmap.c          |    3 ++-
> >  io/open.c           |    3 ++-
> >  io/stat.c           |    5 +++--
> >  libfrog/fsgeom.c    |   18 ++++++++++++++++++
> >  quota/free.c        |    6 +++---
> >  repair/xfs_repair.c |    5 +++--
> >  rtcp/Makefile       |    3 +++
> >  rtcp/xfs_rtcp.c     |    7 ++++---
> >  scrub/phase1.c      |    3 ++-
> >  spaceman/file.c     |    3 ++-
> >  spaceman/info.c     |   25 ++++++++-----------------
> >  16 files changed, 88 insertions(+), 70 deletions(-)
> >  create mode 100644 include/xfrog.h
> 
> Looks good - only nitpick is that the conversion for testing for
> the return code is "rval < 0" and others is just "rval" and the conversion
> doesn't seem consistent.   I ... guess it doesn't really matter, as we're
> returning either 0 or < 0 and never > 0 it just seemed a bit odd...
> 
> i.e.
> 
> > -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> > +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
> 
> vs
> 
> > -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
> > +	if (xfrog_geometry(ffd, &ngeo)) {
> 
> should we pick one?  "< 0" seems to imply that it could return > 0 and
> be ok, which isn't the case, so I'd go for the 2nd type.

Hmm.  xfrog_geometry is a wrapper for ioctl so ... I guess we'll just do
the error < 0 check like we've always done for ioctls:

ret = xfrog_geometry()
if (ret < 0) {
	barf();
}

Will fix.

--D

> > 
> > diff --git a/Makefile b/Makefile
> > index 9204bed8..0edc2700 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -107,6 +107,7 @@ copy: libxlog
> >  mkfs: libxcmd
> >  spaceman: libxcmd
> >  scrub: libhandle libxcmd
> > +rtcp: libfrog
> >  
> >  ifeq ($(HAVE_BUILDDEFS), yes)
> >  include $(BUILDRULES)
> > diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
> > index fef6262c..0bfecf37 100644
> > --- a/fsr/xfs_fsr.c
> > +++ b/fsr/xfs_fsr.c
> > @@ -11,6 +11,7 @@
> >  #include "xfs_bmap_btree.h"
> >  #include "xfs_attr_sf.h"
> >  #include "path.h"
> > +#include "xfrog.h"
> >  
> >  #include <fcntl.h>
> >  #include <errno.h>
> > @@ -83,9 +84,8 @@ int cmp(const void *, const void *);
> >  static void tmp_init(char *mnt);
> >  static char * tmp_next(char *mnt);
> >  static void tmp_close(char *mnt);
> > -int xfs_getgeom(int , xfs_fsop_geom_v1_t * );
> >  
> > -static xfs_fsop_geom_v1_t fsgeom;	/* geometry of active mounted system */
> > +static struct xfs_fsop_geom fsgeom;	/* geometry of active mounted system */
> >  
> >  #define NMOUNT 64
> >  static int numfs;
> > @@ -102,12 +102,6 @@ static int	nfrags = 0;	/* Debug option: Coerse into specific number
> >  				 * of extents */
> >  static int	openopts = O_CREAT|O_EXCL|O_RDWR|O_DIRECT;
> >  
> > -static int
> > -xfs_fsgeometry(int fd, xfs_fsop_geom_v1_t *geom)
> > -{
> > -    return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, geom);
> > -}
> > -
> >  static int
> >  xfs_bulkstat_single(int fd, xfs_ino_t *lastip, xfs_bstat_t *ubuffer)
> >  {
> > @@ -630,7 +624,7 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
> >  		return -1;
> >  	}
> >  
> > -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> > +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
> >  		fsrprintf(_("Skipping %s: could not get XFS geometry\n"),
> >  			  mntdir);
> >  		close(fsfd);
> > @@ -772,7 +766,7 @@ fsrfile(char *fname, xfs_ino_t ino)
> >  	}
> >  
> >  	/* Get the fs geometry */
> > -	if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
> > +	if (xfrog_geometry(fsfd, &fsgeom) < 0 ) {
> >  		fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
> >  		goto out;
> >  	}
> > @@ -1612,18 +1606,6 @@ getnextents(int fd)
> >  	return(nextents);
> >  }
> >  
> > -/*
> > - * Get the fs geometry
> > - */
> > -int
> > -xfs_getgeom(int fd, xfs_fsop_geom_v1_t * fsgeom)
> > -{
> > -	if (xfs_fsgeometry(fd, fsgeom) < 0) {
> > -		return -1;
> > -	}
> > -	return 0;
> > -}
> > -
> >  /*
> >   * Get xfs realtime space information
> >   */
> > diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c
> > index 20089d2b..28dd6d84 100644
> > --- a/growfs/xfs_growfs.c
> > +++ b/growfs/xfs_growfs.c
> > @@ -7,6 +7,7 @@
> >  #include "libxfs.h"
> >  #include "path.h"
> >  #include "fsgeom.h"
> > +#include "xfrog.h"
> >  
> >  static void
> >  usage(void)
> > @@ -165,22 +166,14 @@ main(int argc, char **argv)
> >  	}
> >  
> >  	/* get the current filesystem size & geometry */
> > -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY, &geo) < 0) {
> > -		/*
> > -		 * OK, new xfsctl barfed - back off and try earlier version
> > -		 * as we're probably running an older kernel version.
> > -		 * Only field added in the v2 geometry xfsctl is "logsunit"
> > -		 * so we'll zero that out for later display (as zero).
> > -		 */
> > -		geo.logsunit = 0;
> > -		if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &geo) < 0) {
> > -			fprintf(stderr, _(
> > -				"%s: cannot determine geometry of filesystem"
> > -				" mounted at %s: %s\n"),
> > -				progname, fname, strerror(errno));
> > -			exit(1);
> > -		}
> > +	if (xfrog_geometry(ffd, &geo)) {
> > +		fprintf(stderr, _(
> > +			"%s: cannot determine geometry of filesystem"
> > +			" mounted at %s: %s\n"),
> > +			progname, fname, strerror(errno));
> > +		exit(1);
> >  	}
> > +
> >  	isint = geo.logstart > 0;
> >  
> >  	/*
> > @@ -359,7 +352,7 @@ main(int argc, char **argv)
> >  		}
> >  	}
> >  
> > -	if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
> > +	if (xfrog_geometry(ffd, &ngeo)) {
> >  		fprintf(stderr, _("%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n"),
> >  			progname, strerror(errno));
> >  		exit(1);
> > diff --git a/include/xfrog.h b/include/xfrog.h
> > new file mode 100644
> > index 00000000..5420b47c
> > --- /dev/null
> > +++ b/include/xfrog.h
> > @@ -0,0 +1,22 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2000-2002 Silicon Graphics, Inc.
> > + * All Rights Reserved.
> > + */
> > +#ifndef __XFROG_H__
> > +#define __XFROG_H__
> > +
> > +/*
> > + * XFS Filesystem Random Online Gluecode
> > + * =====================================
> > + *
> > + * These support functions wrap the more complex xfs ioctls so that xfs
> > + * utilities can take advantage of them without having to deal with graceful
> > + * degradation in the face of new ioctls.  They will also provide higher level
> > + * abstractions when possible.
> > + */
> > +
> > +struct xfs_fsop_geom;
> > +int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
> > +
> > +#endif	/* __XFROG_H__ */
> > diff --git a/io/bmap.c b/io/bmap.c
> > index d408826a..5f0d12ca 100644
> > --- a/io/bmap.c
> > +++ b/io/bmap.c
> > @@ -9,6 +9,7 @@
> >  #include "input.h"
> >  #include "init.h"
> >  #include "io.h"
> > +#include "xfrog.h"
> >  
> >  static cmdinfo_t bmap_cmd;
> >  
> > @@ -105,7 +106,7 @@ bmap_f(
> >  		bmv_iflags &= ~(BMV_IF_PREALLOC|BMV_IF_NO_DMAPI_READ);
> >  
> >  	if (vflag) {
> > -		c = xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo);
> > +		c = xfrog_geometry(file->fd, &fsgeo);
> >  		if (c < 0) {
> >  			fprintf(stderr,
> >  				_("%s: can't get geometry [\"%s\"]: %s\n"),
> > diff --git a/io/fsmap.c b/io/fsmap.c
> > index 477c36fc..d3ff7dea 100644
> > --- a/io/fsmap.c
> > +++ b/io/fsmap.c
> > @@ -9,6 +9,7 @@
> >  #include "path.h"
> >  #include "io.h"
> >  #include "input.h"
> > +#include "xfrog.h"
> >  
> >  static cmdinfo_t	fsmap_cmd;
> >  static dev_t		xfs_data_dev;
> > @@ -447,7 +448,7 @@ fsmap_f(
> >  	}
> >  
> >  	if (vflag) {
> > -		c = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &fsgeo);
> > +		c = xfrog_geometry(file->fd, &fsgeo);
> >  		if (c < 0) {
> >  			fprintf(stderr,
> >  				_("%s: can't get geometry [\"%s\"]: %s\n"),
> > diff --git a/io/open.c b/io/open.c
> > index c7f5248a..997df119 100644
> > --- a/io/open.c
> > +++ b/io/open.c
> > @@ -9,6 +9,7 @@
> >  #include "init.h"
> >  #include "io.h"
> >  #include "libxfs.h"
> > +#include "xfrog.h"
> >  
> >  #ifndef __O_TMPFILE
> >  #if defined __alpha__
> > @@ -118,7 +119,7 @@ openfile(
> >  	if (flags & IO_PATH) {
> >  		/* Can't call ioctl() on O_PATH fds */
> >  		memset(geom, 0, sizeof(*geom));
> > -	} else if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
> > +	} else if (xfrog_geometry(fd, geom)) {
> >  		perror("XFS_IOC_FSGEOMETRY");
> >  		close(fd);
> >  		return -1;
> > diff --git a/io/stat.c b/io/stat.c
> > index 37c0b2e8..26b4eb68 100644
> > --- a/io/stat.c
> > +++ b/io/stat.c
> > @@ -12,6 +12,7 @@
> >  #include "io.h"
> >  #include "statx.h"
> >  #include "libxfs.h"
> > +#include "xfrog.h"
> >  
> >  #include <fcntl.h>
> >  
> > @@ -194,8 +195,8 @@ statfs_f(
> >  	}
> >  	if (file->flags & IO_FOREIGN)
> >  		return 0;
> > -	if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
> > -		perror("XFS_IOC_FSGEOMETRY_V1");
> > +	if (xfrog_geometry(file->fd, &fsgeo)) {
> > +		perror("XFS_IOC_FSGEOMETRY");
> >  	} else {
> >  		printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
> >  		printf(_("geom.agcount = %u\n"), fsgeo.agcount);
> > diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c
> > index 8879d161..a6dab3a8 100644
> > --- a/libfrog/fsgeom.c
> > +++ b/libfrog/fsgeom.c
> > @@ -4,6 +4,7 @@
> >   */
> >  #include "libxfs.h"
> >  #include "fsgeom.h"
> > +#include "xfrog.h"
> >  
> >  void
> >  xfs_report_geom(
> > @@ -67,3 +68,20 @@ xfs_report_geom(
> >  		geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks,
> >  			(unsigned long long)geo->rtextents);
> >  }
> > +
> > +/* Try to obtain the xfs geometry. */
> > +int
> > +xfrog_geometry(
> > +	int			fd,
> > +	struct xfs_fsop_geom	*fsgeo)
> > +{
> > +	int			ret;
> > +
> > +	memset(fsgeo, 0, sizeof(*fsgeo));
> > +
> > +	ret = ioctl(fd, XFS_IOC_FSGEOMETRY, fsgeo);
> > +	if (!ret)
> > +		return 0;
> > +
> > +	return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
> > +}
> > diff --git a/quota/free.c b/quota/free.c
> > index 1d13006e..f47001bf 100644
> > --- a/quota/free.c
> > +++ b/quota/free.c
> > @@ -8,6 +8,7 @@
> >  #include "command.h"
> >  #include "init.h"
> >  #include "quota.h"
> > +#include "xfrog.h"
> >  
> >  static cmdinfo_t free_cmd;
> >  
> > @@ -67,9 +68,8 @@ mount_free_space_data(
> >  	}
> >  
> >  	if (!(mount->fs_flags & FS_FOREIGN)) {
> > -		if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSGEOMETRY_V1,
> > -							&fsgeo)) < 0) {
> > -			perror("XFS_IOC_FSGEOMETRY_V1");
> > +		if (xfrog_geometry(fd, &fsgeo)) {
> > +			perror("XFS_IOC_FSGEOMETRY");
> >  			close(fd);
> >  			return 0;
> >  		}
> > diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
> > index 9657503f..e6717d3c 100644
> > --- a/repair/xfs_repair.c
> > +++ b/repair/xfs_repair.c
> > @@ -22,6 +22,7 @@
> >  #include "dinode.h"
> >  #include "slab.h"
> >  #include "rmap.h"
> > +#include "xfrog.h"
> >  
> >  /*
> >   * option tables for getsubopt calls
> > @@ -636,11 +637,11 @@ check_fs_vs_host_sectsize(
> >  {
> >  	int	fd;
> >  	long	old_flags;
> > -	struct xfs_fsop_geom_v1 geom = { 0 };
> > +	struct xfs_fsop_geom	geom = { 0 };
> >  
> >  	fd = libxfs_device_to_fd(x.ddev);
> >  
> > -	if (ioctl(fd, XFS_IOC_FSGEOMETRY_V1, &geom) < 0) {
> > +	if (xfrog_geometry(fd, &geom)) {
> >  		do_log(_("Cannot get host filesystem geometry.\n"
> >  	"Repair may fail if there is a sector size mismatch between\n"
> >  	"the image and the host filesystem.\n"));
> > diff --git a/rtcp/Makefile b/rtcp/Makefile
> > index 808b5378..264b4f27 100644
> > --- a/rtcp/Makefile
> > +++ b/rtcp/Makefile
> > @@ -9,6 +9,9 @@ LTCOMMAND = xfs_rtcp
> >  CFILES = xfs_rtcp.c
> >  LLDFLAGS = -static
> >  
> > +LLDLIBS = $(LIBFROG)
> > +LTDEPENDENCIES = $(LIBFROG)
> > +
> >  default: depend $(LTCOMMAND)
> >  
> >  include $(BUILDRULES)
> > diff --git a/rtcp/xfs_rtcp.c b/rtcp/xfs_rtcp.c
> > index f928a86a..0b37ee89 100644
> > --- a/rtcp/xfs_rtcp.c
> > +++ b/rtcp/xfs_rtcp.c
> > @@ -5,6 +5,7 @@
> >   */
> >  
> >  #include "libxfs.h"
> > +#include "xfrog.h"
> >  
> >  int rtcp(char *, char *, int);
> >  int xfsrtextsize(char *path);
> > @@ -368,8 +369,8 @@ rtcp( char *source, char *target, int fextsize)
> >  int
> >  xfsrtextsize( char *path)
> >  {
> > -	int fd, rval, rtextsize;
> > -	xfs_fsop_geom_v1_t geo;
> > +	struct xfs_fsop_geom	geo;
> > +	int			fd, rval, rtextsize;
> >  
> >  	fd = open( path, O_RDONLY );
> >  	if ( fd < 0 ) {
> > @@ -377,7 +378,7 @@ xfsrtextsize( char *path)
> >  			progname, path, strerror(errno));
> >  		return -1;
> >  	}
> > -	rval = xfsctl( path, fd, XFS_IOC_FSGEOMETRY_V1, &geo );
> > +	rval = xfrog_geometry(fd, &geo);
> >  	close(fd);
> >  	if ( rval < 0 )
> >  		return -1;
> > diff --git a/scrub/phase1.c b/scrub/phase1.c
> > index 04a5f4a9..5ab2a4fe 100644
> > --- a/scrub/phase1.c
> > +++ b/scrub/phase1.c
> > @@ -26,6 +26,7 @@
> >  #include "disk.h"
> >  #include "scrub.h"
> >  #include "repair.h"
> > +#include "xfrog.h"
> >  
> >  /* Phase 1: Find filesystem geometry (and clean up after) */
> >  
> > @@ -129,7 +130,7 @@ _("Does not appear to be an XFS filesystem!"));
> >  	}
> >  
> >  	/* Retrieve XFS geometry. */
> > -	error = ioctl(ctx->mnt_fd, XFS_IOC_FSGEOMETRY, &ctx->geo);
> > +	error = xfrog_geometry(ctx->mnt_fd, &ctx->geo);
> >  	if (error) {
> >  		str_errno(ctx, ctx->mntpoint);
> >  		return false;
> > diff --git a/spaceman/file.c b/spaceman/file.c
> > index 7e33e07e..9e983d79 100644
> > --- a/spaceman/file.c
> > +++ b/spaceman/file.c
> > @@ -6,6 +6,7 @@
> >   */
> >  
> >  #include "libxfs.h"
> > +#include "xfrog.h"
> >  #include <sys/mman.h>
> >  #include "command.h"
> >  #include "input.h"
> > @@ -56,7 +57,7 @@ openfile(
> >  		return -1;
> >  	}
> >  
> > -	if (ioctl(fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
> > +	if (xfrog_geometry(fd, geom)) {
> >  		if (errno == ENOTTY)
> >  			fprintf(stderr,
> >  _("%s: Not on a mounted XFS filesystem.\n"),
> > diff --git a/spaceman/info.c b/spaceman/info.c
> > index 01d0744a..e4dedee2 100644
> > --- a/spaceman/info.c
> > +++ b/spaceman/info.c
> > @@ -4,6 +4,7 @@
> >   * Author: Darrick J. Wong <darrick.wong@oracle.com>
> >   */
> >  #include "libxfs.h"
> > +#include "xfrog.h"
> >  #include "command.h"
> >  #include "init.h"
> >  #include "path.h"
> > @@ -37,24 +38,14 @@ info_f(
> >  	}
> >  
> >  	/* get the current filesystem size & geometry */
> > -	error = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &geo);
> > +	error = xfrog_geometry(file->fd, &geo);
> >  	if (error) {
> > -		/*
> > -		 * OK, new xfsctl barfed - back off and try earlier version
> > -		 * as we're probably running an older kernel version.
> > -		 * Only field added in the v2 geometry xfsctl is "logsunit"
> > -		 * so we'll zero that out for later display (as zero).
> > -		 */
> > -		geo.logsunit = 0;
> > -		error = ioctl(file->fd, XFS_IOC_FSGEOMETRY_V1, &geo);
> > -		if (error) {
> > -			fprintf(stderr, _(
> > -				"%s: cannot determine geometry of filesystem"
> > -				" mounted at %s: %s\n"),
> > -				progname, file->name, strerror(errno));
> > -			exitcode = 1;
> > -			return 0;
> > -		}
> > +		fprintf(stderr, _(
> > +			"%s: cannot determine geometry of filesystem"
> > +			" mounted at %s: %s\n"),
> > +			progname, file->name, strerror(errno));
> > +		exitcode = 1;
> > +		return 0;
> >  	}
> >  
> >  	xfs_report_geom(&geo, file->fs_path.fs_name, file->fs_path.fs_log,
> > 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/12] libfrog: don't set negative errno in conversion functions
  2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
  2019-06-20 18:58   ` Eric Sandeen
@ 2019-06-25 11:02   ` Christoph Hellwig
  1 sibling, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2019-06-25 11:02 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll
  2019-06-20 16:49 ` [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll Darrick J. Wong
  2019-06-20 19:08   ` Eric Sandeen
@ 2019-06-25 11:02   ` Christoph Hellwig
  1 sibling, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2019-06-25 11:02 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

On Thu, Jun 20, 2019 at 09:49:42AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> cvt_u64 converts a string to an unsigned 64-bit number, so it should use
> strtoull, not strtoll because we don't want negative numbers here.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 03/12] libfrog: refactor online geometry queries
  2019-06-20 16:49 ` [PATCH 03/12] libfrog: refactor online geometry queries Darrick J. Wong
  2019-06-20 19:16   ` Eric Sandeen
@ 2019-06-25 14:28   ` Christoph Hellwig
  1 sibling, 0 replies; 26+ messages in thread
From: Christoph Hellwig @ 2019-06-25 14:28 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: sandeen, linux-xfs

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls
  2019-06-20 16:50 ` [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls Darrick J. Wong
@ 2019-06-25 23:53   ` Darrick J. Wong
  0 siblings, 0 replies; 26+ messages in thread
From: Darrick J. Wong @ 2019-06-25 23:53 UTC (permalink / raw)
  To: sandeen; +Cc: linux-xfs

On Thu, Jun 20, 2019 at 09:50:20AM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Refactor all the INUMBERS ioctl callsites into helper functions.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  include/xfrog.h    |    4 ++++
>  io/imap.c          |   32 +++++++++++++++-----------------
>  io/open.c          |   20 ++++++++------------
>  libfrog/bulkstat.c |   19 +++++++++++++++++++
>  scrub/fscounters.c |   18 +++++++-----------
>  scrub/inodes.c     |   23 +++++++++--------------
>  6 files changed, 62 insertions(+), 54 deletions(-)
> 
> 
> diff --git a/include/xfrog.h b/include/xfrog.h
> index 176a2e1d..dab1214d 100644
> --- a/include/xfrog.h
> +++ b/include/xfrog.h
> @@ -107,4 +107,8 @@ int xfrog_bulkstat_single(struct xfrog *froggie, uint64_t ino,
>  int xfrog_bulkstat(struct xfrog *froggie, uint64_t *lastino, uint32_t icount,
>  		struct xfs_bstat *ubuffer, uint32_t *ocount);
>  
> +struct xfs_inogrp;
> +int xfrog_inumbers(struct xfrog *froggie, uint64_t *lastino, uint32_t icount,
> +		struct xfs_inogrp *ubuffer, uint32_t *ocount);
> +
>  #endif	/* __XFROG_H__ */
> diff --git a/io/imap.c b/io/imap.c
> index fbc8e9e1..05a4985d 100644
> --- a/io/imap.c
> +++ b/io/imap.c
> @@ -8,18 +8,20 @@
>  #include "input.h"
>  #include "init.h"
>  #include "io.h"
> +#include "xfrog.h"
>  
>  static cmdinfo_t imap_cmd;
>  
>  static int
>  imap_f(int argc, char **argv)
>  {
> -	int		count;
> -	int		nent;
> -	int		i;
> -	__u64		last = 0;
> -	xfs_inogrp_t	*t;
> -	xfs_fsop_bulkreq_t bulkreq;
> +	struct xfrog		frog = XFROG_INIT(file->fd);
> +	struct xfs_inogrp	*t;
> +	uint64_t		last = 0;
> +	uint32_t		count;
> +	uint32_t		nent;
> +	int			i;
> +	int			error;
>  
>  	if (argc != 2)
>  		nent = 1;
> @@ -30,14 +32,8 @@ imap_f(int argc, char **argv)
>  	if (!t)
>  		return 0;
>  
> -	bulkreq.lastip  = &last;
> -	bulkreq.icount  = nent;
> -	bulkreq.ubuffer = (void *)t;
> -	bulkreq.ocount  = &count;
> -
> -	while (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, &bulkreq) == 0) {
> -		if (count == 0)
> -			goto out_free;
> +	while ((error = xfrog_inumbers(&frog, &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,
> @@ -45,9 +41,11 @@ imap_f(int argc, char **argv)
>  				(unsigned long long)t[i].xi_allocmask);
>  		}
>  	}
> -	perror("xfsctl(XFS_IOC_FSINUMBERS)");
> -	exitcode = 1;
> -out_free:
> +
> +	if (error) {
> +		perror("xfsctl(XFS_IOC_FSINUMBERS)");
> +		exitcode = 1;
> +	}
>  	free(t);
>  	return 0;
>  }
> diff --git a/io/open.c b/io/open.c
> index 36e07dc3..35bcd23a 100644
> --- a/io/open.c
> +++ b/io/open.c
> @@ -669,24 +669,20 @@ inode_help(void)
>  "\n"));
>  }
>  
> +#define IGROUP_NR	(1024)
>  static __u64
>  get_last_inode(void)
>  {
> -	__u64			lastip = 0;
> -	__u64			lastgrp = 0;
> -	__s32			ocount = 0;
> +	struct xfrog		frog = XFROG_INIT(file->fd);
> +	uint64_t		lastip = 0;
> +	uint32_t		lastgrp = 0;
> +	uint32_t		ocount = 0;
>  	__u64			last_ino;
> -	struct xfs_inogrp	igroup[1024];
> -	struct xfs_fsop_bulkreq	bulkreq;
> -
> -	bulkreq.lastip = &lastip;
> -	bulkreq.ubuffer = &igroup;
> -	bulkreq.icount = sizeof(igroup) / sizeof(struct xfs_inogrp);
> -	bulkreq.ocount = &ocount;
> +	struct xfs_inogrp	igroup[IGROUP_NR];
>  
>  	for (;;) {
> -		if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS,
> -				&bulkreq)) {
> +		if (xfrog_inumbers(&frog, &lastip, IGROUP_NR, igroup,
> +					&ocount)) {
>  			perror("XFS_IOC_FSINUMBERS");
>  			return 0;
>  		}
> diff --git a/libfrog/bulkstat.c b/libfrog/bulkstat.c
> index 30a9e6bc..9ce238b8 100644
> --- a/libfrog/bulkstat.c
> +++ b/libfrog/bulkstat.c
> @@ -42,3 +42,22 @@ xfrog_bulkstat(
>  
>  	return ioctl(froggie->fd, XFS_IOC_FSBULKSTAT, &bulkreq);
>  }
> +
> +/* Query inode allocation bitmask information. */
> +int
> +xfrog_inumbers(
> +	struct xfrog		*froggie,
> +	uint64_t		*lastino,
> +	uint32_t		icount,
> +	struct xfs_inogrp	*ubuffer,
> +	uint32_t		*ocount)
> +{
> +	struct xfs_fsop_bulkreq	bulkreq = {
> +		.lastip		= (__u64 *)lastino,
> +		.icount		= icount,
> +		.ubuffer	= ubuffer,
> +		.ocount		= (__s32 *)ocount,
> +	};
> +
> +	return ioctl(froggie->fd, XFS_IOC_FSINUMBERS, &bulkreq);
> +}
> diff --git a/scrub/fscounters.c b/scrub/fscounters.c
> index adb79b50..cd216b30 100644
> --- a/scrub/fscounters.c
> +++ b/scrub/fscounters.c
> @@ -15,6 +15,7 @@
>  #include "xfs_scrub.h"
>  #include "common.h"
>  #include "fscounters.h"
> +#include "xfrog.h"
>  
>  /*
>   * Filesystem counter collection routines.  We can count the number of
> @@ -41,26 +42,21 @@ xfs_count_inodes_range(
>  	uint64_t		last_ino,
>  	uint64_t		*count)
>  {
> -	struct xfs_fsop_bulkreq	igrpreq = {NULL};
>  	struct xfs_inogrp	inogrp;
> -	__u64			igrp_ino;
> +	uint64_t		igrp_ino;
>  	uint64_t		nr = 0;
> -	__s32			igrplen = 0;
> +	uint32_t		igrplen = 0;
>  	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;
> -
>  	igrp_ino = first_ino;
> -	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
> -	while (!error && igrplen && inogrp.xi_startino < last_ino) {
> +	while (!(error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
> +			&igrplen))) {
> +		if (igrplen == 0 || inogrp.xi_startino >= last_ino)
> +			break;
>  		nr += inogrp.xi_alloccount;
> -		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
>  	}
>  
>  	if (error) {
> diff --git a/scrub/inodes.c b/scrub/inodes.c
> index 09dd0055..dea925be 100644
> --- a/scrub/inodes.c
> +++ b/scrub/inodes.c
> @@ -90,17 +90,16 @@ xfs_iterate_inodes_range(
>  	xfs_inode_iter_fn	fn,
>  	void			*arg)
>  {
> -	struct xfs_fsop_bulkreq	igrpreq = {NULL};
>  	struct xfs_handle	handle;
>  	struct xfs_inogrp	inogrp;
>  	struct xfs_bstat	bstat[XFS_INODES_PER_CHUNK];
>  	char			idescr[DESCR_BUFSZ];
>  	char			buf[DESCR_BUFSZ];
>  	struct xfs_bstat	*bs;
> -	__u64			igrp_ino;
> +	uint64_t		igrp_ino;
>  	uint64_t		ino;
>  	uint32_t		bulklen = 0;
> -	__s32			igrplen = 0;
> +	uint32_t		igrplen = 0;
>  	bool			moveon = true;
>  	int			i;
>  	int			error;
> @@ -109,11 +108,6 @@ xfs_iterate_inodes_range(
>  
>  	memset(bstat, 0, XFS_INODES_PER_CHUNK * sizeof(struct xfs_bstat));
>  
> -	igrpreq.lastip  = &igrp_ino;
> -	igrpreq.icount  = 1;
> -	igrpreq.ubuffer = &inogrp;
> -	igrpreq.ocount  = &igrplen;
> -
>  	memcpy(&handle.ha_fsid, fshandle, sizeof(handle.ha_fsid));
>  	handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
>  			sizeof(handle.ha_fid.fid_len);
> @@ -121,8 +115,11 @@ xfs_iterate_inodes_range(
>  
>  	/* Find the inode chunk & alloc mask */
>  	igrp_ino = first_ino;
> -	error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
> -	while (!error && igrplen) {
> +	while (!(error = xfrog_inumbers(&ctx->mnt, &igrp_ino, 1, &inogrp,
> +			&igrplen))) {
> +		if (igrplen == 0)
> +			break;
> +
>  		/* Load the inodes. */
>  		ino = inogrp.xi_startino - 1;
>  
> @@ -131,7 +128,7 @@ xfs_iterate_inodes_range(
>  		 * there are more than 64 inodes per block.  Skip these.
>  		 */
>  		if (inogrp.xi_alloccount == 0)
> -			goto igrp_retry;
> +			continue;
>  		error = xfrog_bulkstat(&ctx->mnt, &ino, inogrp.xi_alloccount,
>  				bstat, &bulklen);
>  		if (error)
> @@ -155,7 +152,7 @@ xfs_iterate_inodes_range(
>  				stale_count++;
>  				if (stale_count < 30) {
>  					igrp_ino = inogrp.xi_startino;
> -					goto igrp_retry;
> +					continue;

NAK.

This doesn't continue the outer loop like the old code did.

--D

>  				}
>  				snprintf(idescr, DESCR_BUFSZ, "inode %"PRIu64,
>  						(uint64_t)bs->bs_ino);
> @@ -177,8 +174,6 @@ _("Changed too many times during scan; giving up."));
>  		}
>  
>  		stale_count = 0;
> -igrp_retry:
> -		error = ioctl(ctx->mnt.fd, XFS_IOC_FSINUMBERS, &igrpreq);
>  	}
>  
>  err:
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2019-06-25 23:53 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-20 16:49 [PATCH v3 00/12] xfsprogs-5.1: fix various problems Darrick J. Wong
2019-06-20 16:49 ` [PATCH 01/12] libfrog: don't set negative errno in conversion functions Darrick J. Wong
2019-06-20 18:58   ` Eric Sandeen
2019-06-25 11:02   ` Christoph Hellwig
2019-06-20 16:49 ` [PATCH 02/12] libfrog: cvt_u64 should use strtoull, not strtoll Darrick J. Wong
2019-06-20 19:08   ` Eric Sandeen
2019-06-25 11:02   ` Christoph Hellwig
2019-06-20 16:49 ` [PATCH 03/12] libfrog: refactor online geometry queries Darrick J. Wong
2019-06-20 19:16   ` Eric Sandeen
2019-06-20 21:02     ` Darrick J. Wong
2019-06-25 14:28   ` Christoph Hellwig
2019-06-20 16:49 ` [PATCH 04/12] libfrog: introduce xfrog context Darrick J. Wong
2019-06-20 19:40   ` Eric Sandeen
2019-06-20 16:50 ` [PATCH 05/12] libfrog: store more inode and block geometry in struct xfrog Darrick J. Wong
2019-06-20 16:50 ` [PATCH 06/12] libfrog: create online fs geometry converters Darrick J. Wong
2019-06-20 16:50 ` [PATCH 07/12] libfrog: refactor open-coded bulkstat calls Darrick J. Wong
2019-06-20 16:50 ` [PATCH 08/12] libfrog: refactor open-coded INUMBERS calls Darrick J. Wong
2019-06-25 23:53   ` Darrick J. Wong
2019-06-20 16:50 ` [PATCH 09/12] mkfs: validate start and end of aligned logs Darrick J. Wong
2019-06-20 19:46   ` Eric Sandeen
2019-06-20 16:50 ` [PATCH 10/12] xfs_io: repair_f should use its own name Darrick J. Wong
2019-06-20 19:52   ` Eric Sandeen
2019-06-20 16:50 ` [PATCH 11/12] libxfs-diff: try harder to find the kernel equivalent libxfs files Darrick J. Wong
2019-06-20 19:53   ` Eric Sandeen
2019-06-20 19:57     ` Darrick J. Wong
2019-06-20 16:50 ` [PATCH 12/12] xfs_db: add a function to compute btree geometry Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.