]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
libfrog: refactor online geometry queries
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 9 Sep 2019 19:36:57 +0000 (15:36 -0400)
committerEric Sandeen <sandeen@redhat.com>
Mon, 9 Sep 2019 19:36:57 +0000 (15:36 -0400)
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>
Reviewed-by: Allison Collins <allison.henderson@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
[sandeen: remove 5.2.1 compat hack now that we have the wrapper]
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
18 files changed:
Makefile
fsr/xfs_fsr.c
growfs/xfs_growfs.c
include/fsgeom.h
io/bmap.c
io/fsmap.c
io/open.c
io/stat.c
libfrog/fsgeom.c
libxfs/xfs_fs.h
quota/free.c
repair/xfs_repair.c
rtcp/Makefile
rtcp/xfs_rtcp.c
scrub/common.h
scrub/phase1.c
spaceman/file.c
spaceman/info.c

index 9204bed834fe92762c7da2a86f5729c152e82220..0edc2700933d88132fd23b7c1caa321a903a4513 100644 (file)
--- 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)
index 1963a05eb36ed7fad55d41193b917b7df10e077f..50faddc80cd442ce0e8541063094908e0e3c1f0a 100644 (file)
@@ -11,6 +11,7 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_attr_sf.h"
 #include "path.h"
+#include "fsgeom.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 , struct xfs_fsop_geom_v1 * );
 
-static struct xfs_fsop_geom_v1 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, struct xfs_fsop_geom_v1 *geom)
-{
-    return ioctl(fd, XFS_IOC_FSGEOMETRY_V1, geom);
-}
-
 static int
 xfs_bulkstat_single(int fd, xfs_ino_t *lastip, struct xfs_bstat *ubuffer)
 {
@@ -630,7 +624,8 @@ fsrfs(char *mntdir, xfs_ino_t startino, int targetrange)
                return -1;
        }
 
-       if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
+       ret = xfrog_geometry(fsfd, &fsgeom);
+       if (ret) {
                fsrprintf(_("Skipping %s: could not get XFS geometry\n"),
                          mntdir);
                close(fsfd);
@@ -772,7 +767,8 @@ fsrfile(char *fname, xfs_ino_t ino)
        }
 
        /* Get the fs geometry */
-       if (xfs_getgeom(fsfd, &fsgeom) < 0 ) {
+       error = xfrog_geometry(fsfd, &fsgeom);
+       if (error) {
                fsrprintf(_("Unable to get geom on fs for: %s\n"), fname);
                goto out;
        }
@@ -1612,18 +1608,6 @@ getnextents(int fd)
        return(nextents);
 }
 
-/*
- * Get the fs geometry
- */
-int
-xfs_getgeom(int fd, struct xfs_fsop_geom_v1 *fsgeom)
-{
-       if (xfs_fsgeometry(fd, fsgeom) < 0) {
-               return -1;
-       }
-       return 0;
-}
-
 /*
  * Get xfs realtime space information
  */
index 20089d2bd8d35c421b2e8fe9197b23d4aada8e89..4d48617ad3d03452fefeba50c232964c9602f0e0 100644 (file)
@@ -63,6 +63,7 @@ main(int argc, char **argv)
        fs_path_t               *fs;    /* mount point information */
        libxfs_init_t           xi;     /* libxfs structure */
        char                    rpath[PATH_MAX];
+       int                     ret;
 
        progname = basename(argv[0]);
        setlocale(LC_ALL, "");
@@ -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);
-               }
+       ret = xfrog_geometry(ffd, &geo);
+       if (ret) {
+               fprintf(stderr,
+       _("%s: cannot determine geometry of filesystem mounted at %s: %s\n"),
+                       progname, fname, strerror(ret));
+               exit(1);
        }
+
        isint = geo.logstart > 0;
 
        /*
@@ -359,9 +352,10 @@ main(int argc, char **argv)
                }
        }
 
-       if (xfsctl(fname, ffd, XFS_IOC_FSGEOMETRY_V1, &ngeo) < 0) {
+       ret = xfrog_geometry(ffd, &ngeo);
+       if (ret) {
                fprintf(stderr, _("%s: XFS_IOC_FSGEOMETRY xfsctl failed: %s\n"),
-                       progname, strerror(errno));
+                       progname, strerror(ret));
                exit(1);
        }
        if (geo.datablocks != ngeo.datablocks)
index ed8c9b1ef27f9f42724bce82756219ea5204e46f..8ea16a35a97e933ab78cdf05d2adc7577c141c4c 100644 (file)
@@ -7,5 +7,6 @@
 
 void xfs_report_geom(struct xfs_fsop_geom *geo, const char *mntpoint,
                const char *logname, const char *rtname);
+int xfrog_geometry(int fd, struct xfs_fsop_geom *fsgeo);
 
 #endif /* _LIBFROG_FSGEOM_H_ */
index d408826a2278792768435a2a2885a4308244cd43..d4262cf2b7388e559c264320e40fdd0d4f515f50 100644 (file)
--- a/io/bmap.c
+++ b/io/bmap.c
@@ -9,6 +9,7 @@
 #include "input.h"
 #include "init.h"
 #include "io.h"
+#include "fsgeom.h"
 
 static cmdinfo_t bmap_cmd;
 
@@ -105,11 +106,11 @@ 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);
-               if (c < 0) {
+               c = xfrog_geometry(file->fd, &fsgeo);
+               if (c) {
                        fprintf(stderr,
                                _("%s: can't get geometry [\"%s\"]: %s\n"),
-                               progname, file->name, strerror(errno));
+                               progname, file->name, strerror(c));
                        exitcode = 1;
                        return 0;
                }
index 477c36fcbd58442f69a0642b0a20240de7f49138..67baa81786f041f882ae9178048388b718b7a2f8 100644 (file)
@@ -9,6 +9,7 @@
 #include "path.h"
 #include "io.h"
 #include "input.h"
+#include "fsgeom.h"
 
 static cmdinfo_t       fsmap_cmd;
 static dev_t           xfs_data_dev;
@@ -447,8 +448,8 @@ fsmap_f(
        }
 
        if (vflag) {
-               c = ioctl(file->fd, XFS_IOC_FSGEOMETRY, &fsgeo);
-               if (c < 0) {
+               c = xfrog_geometry(file->fd, &fsgeo);
+               if (c) {
                        fprintf(stderr,
                                _("%s: can't get geometry [\"%s\"]: %s\n"),
                                progname, file->name, strerror(errno));
index c7f5248a9b13353f597b2a98f9deca9ce72337f4..ba6c496939165151f2f52eb6ed566fdac38981e0 100644 (file)
--- a/io/open.c
+++ b/io/open.c
@@ -9,6 +9,7 @@
 #include "init.h"
 #include "io.h"
 #include "libxfs.h"
+#include "fsgeom.h"
 
 #ifndef __O_TMPFILE
 #if defined __alpha__
@@ -118,10 +119,16 @@ 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) {
-               perror("XFS_IOC_FSGEOMETRY");
-               close(fd);
-               return -1;
+       } else {
+               int     ret;
+
+               ret = xfrog_geometry(fd, geom);
+               if (ret) {
+                       errno = ret;
+                       perror("XFS_IOC_FSGEOMETRY");
+                       close(fd);
+                       return -1;
+               }
        }
 
        if (!(flags & (IO_READONLY | IO_PATH)) && (flags & IO_REALTIME)) {
index 37c0b2e81516e4008ed54fe1f28cca484faa3f3f..4c1cc83dd1326708d5c4cb251908ce480eb8c1da 100644 (file)
--- a/io/stat.c
+++ b/io/stat.c
@@ -12,6 +12,7 @@
 #include "io.h"
 #include "statx.h"
 #include "libxfs.h"
+#include "fsgeom.h"
 
 #include <fcntl.h>
 
@@ -178,6 +179,7 @@ statfs_f(
        struct xfs_fsop_counts  fscounts;
        struct xfs_fsop_geom    fsgeo;
        struct statfs           st;
+       int                     ret;
 
        printf(_("fd.path = \"%s\"\n"), file->name);
        if (platform_fstatfs(file->fd, &st) < 0) {
@@ -194,8 +196,10 @@ 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");
+       ret = xfrog_geometry(file->fd, &fsgeo);
+       if (ret) {
+               errno = ret;
+               perror("XFS_IOC_FSGEOMETRY");
        } else {
                printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
                printf(_("geom.agcount = %u\n"), fsgeo.agcount);
index 8879d161cce46319b720bf9030d33cd912f1420d..20a92ec1ad9a938f54cf8f7632c7b9610b8acf50 100644 (file)
@@ -67,3 +67,28 @@ xfs_report_geom(
                geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks,
                        (unsigned long long)geo->rtextents);
 }
+
+/* Try to obtain the xfs geometry.  On error returns a positive error code. */
+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;
+
+       ret = ioctl(fd, XFS_IOC_FSGEOMETRY_V4, fsgeo);
+       if (!ret)
+               return 0;
+
+       ret = ioctl(fd, XFS_IOC_FSGEOMETRY_V1, fsgeo);
+       if (!ret)
+               return 0;
+
+       return errno;
+}
index 67fceffc7e07d6c952cc1d83815078c9dbb0878a..31ac63233848da5aec7059f9777d776958aa1ee5 100644 (file)
@@ -822,9 +822,7 @@ struct xfs_scrub_metadata {
 #define XFS_IOC_ATTRMULTI_BY_HANDLE  _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)
 #define XFS_IOC_FSGEOMETRY_V4       _IOR ('X', 124, struct xfs_fsop_geom_v4)
 #define XFS_IOC_GOINGDOWN           _IOR ('X', 125, uint32_t)
-/* For compatibility, for now */
-/* #define XFS_IOC_FSGEOMETRY       _IOR ('X', 126, struct xfs_fsop_geom_v5) */
-#define XFS_IOC_FSGEOMETRY XFS_IOC_FSGEOMETRY_V4
+#define XFS_IOC_FSGEOMETRY          _IOR ('X', 126, struct xfs_fsop_geom)
 #define XFS_IOC_BULKSTAT            _IOR ('X', 127, struct xfs_bulkstat_req)
 #define XFS_IOC_INUMBERS            _IOR ('X', 128, struct xfs_inumbers_req)
 
index 1d13006ed49b48d322cba80bc94d70ed2f0abb5b..a8b6bd1f0c19e8e0771ed6e35920a075399c56d5 100644 (file)
@@ -8,6 +8,7 @@
 #include "command.h"
 #include "init.h"
 #include "quota.h"
+#include "fsgeom.h"
 
 static cmdinfo_t free_cmd;
 
@@ -51,7 +52,7 @@ mount_free_space_data(
        struct xfs_fsop_geom    fsgeo;
        struct statfs           st;
        uint64_t                logsize, count, free;
-       int                     fd;
+       int                     fd, ret;
 
        if ((fd = open(mount->fs_dir, O_RDONLY)) < 0) {
                exitcode = 1;
@@ -67,9 +68,10 @@ 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");
+               ret = xfrog_geometry(fd, &fsgeo);
+               if (ret) {
+                       errno = ret;
+                       perror("XFS_IOC_FSGEOMETRY");
                        close(fd);
                        return 0;
                }
index ce70e2de1553b017216b8837a786090419bf9248..e414c4fb41755eeefbd356c6b4941151ba3a8c39 100644 (file)
@@ -22,6 +22,7 @@
 #include "dinode.h"
 #include "slab.h"
 #include "rmap.h"
+#include "fsgeom.h"
 
 /*
  * option tables for getsubopt calls
@@ -634,13 +635,14 @@ static void
 check_fs_vs_host_sectsize(
        struct xfs_sb   *sb)
 {
-       int     fd;
+       int     fd, ret;
        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) {
+       ret = xfrog_geometry(fd, &geom);
+       if (ret) {
                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"));
index 808b53781c400052ff051da1cb88eb65049d68c2..264b4f27b5fddbb834d9fecf75655dc8217fceae 100644 (file)
@@ -9,6 +9,9 @@ LTCOMMAND = xfs_rtcp
 CFILES = xfs_rtcp.c
 LLDFLAGS = -static
 
+LLDLIBS = $(LIBFROG)
+LTDEPENDENCIES = $(LIBFROG)
+
 default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
index 1027c913f2edbc64101fce6648f00f6d2b71bb39..f6ef0e6c6f2424a541a6354a8800e8b5243962a5 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include "libxfs.h"
+#include "fsgeom.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;
-       struct xfs_fsop_geom_v1 geo;
+       struct xfs_fsop_geom    geo;
+       int                     fd, rval, rtextsize;
 
        fd = open( path, O_RDONLY );
        if ( fd < 0 ) {
@@ -377,9 +378,9 @@ 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 )
+       if (rval)
                return -1;
 
        rtextsize = geo.rtextsize * geo.blocksize;
index e85a0333c728265773c1a4d0ffd62702f22f6492..3355589127dc456407b1b517fac469c992d70932 100644 (file)
@@ -28,6 +28,8 @@ void __str_out(struct scrub_ctx *ctx, const char *descr, enum error_level level,
 
 #define str_errno(ctx, str) \
        __str_out(ctx, str, S_ERROR,    errno,  __FILE__, __LINE__, NULL)
+#define str_liberror(ctx, error, str) \
+       __str_out(ctx, str, S_ERROR,    error,  __FILE__, __LINE__, NULL)
 #define str_error(ctx, str, ...) \
        __str_out(ctx, str, S_ERROR,    0,      __FILE__, __LINE__, __VA_ARGS__)
 #define str_warn(ctx, str, ...) \
index 04a5f4a9209924b5e23ea4dd7b07229407567fae..9a2edf29a2b6606d41abc65348601d2e73aba56f 100644 (file)
@@ -26,6 +26,7 @@
 #include "disk.h"
 #include "scrub.h"
 #include "repair.h"
+#include "fsgeom.h"
 
 /* Phase 1: Find filesystem geometry (and clean up after) */
 
@@ -129,9 +130,9 @@ _("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);
+               str_liberror(ctx, error, _("Retrieving XFS geometry"));
                return false;
        }
 
index 7e33e07e42af5d78f203b0e964fff8048c24edb0..72ef27f3c22a1082d7655cfa90ee6391307c10a7 100644 (file)
@@ -12,6 +12,7 @@
 #include "init.h"
 #include "path.h"
 #include "space.h"
+#include "fsgeom.h"
 
 static cmdinfo_t print_cmd;
 
@@ -48,7 +49,7 @@ openfile(
        struct fs_path  *fs_path)
 {
        struct fs_path  *fsp;
-       int             fd;
+       int             fd, ret;
 
        fd = open(path, 0);
        if (fd < 0) {
@@ -56,13 +57,16 @@ openfile(
                return -1;
        }
 
-       if (ioctl(fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
-               if (errno == ENOTTY)
+       ret = xfrog_geometry(fd, geom);
+       if (ret) {
+               if (ret == ENOTTY)
                        fprintf(stderr,
 _("%s: Not on a mounted XFS filesystem.\n"),
                                        path);
-               else
+               else {
+                       errno = ret;
                        perror("XFS_IOC_FSGEOMETRY");
+               }
                close(fd);
                return -1;
        }
index 01d0744a14fb3fb88ed8ce4dad190458643167fe..151594a8b806519628c8dbd891c968e1713fa92d 100644 (file)
@@ -37,24 +37,13 @@ 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(error));
+               exitcode = 1;
+               return 0;
        }
 
        xfs_report_geom(&geo, file->fs_path.fs_name, file->fs_path.fs_log,