]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Allow tools to use direct IO on Linux when reading from the device, if teh device...
authorNathan Scott <nathans@sgi.com>
Tue, 8 Aug 2006 15:32:10 +0000 (15:32 +0000)
committerNathan Scott <nathans@sgi.com>
Tue, 8 Aug 2006 15:32:10 +0000 (15:32 +0000)
Merge of master-melb:xfs-cmds:26728a by kenmcd.

19 files changed:
copy/xfs_copy.c
include/libxfs.h
libxfs/darwin.c
libxfs/freebsd.c
libxfs/init.c
libxfs/init.h
libxfs/irix.c
libxfs/linux.c
libxfs/rdwr.c
mkfs/xfs_mkfs.c
po/Makefile
repair/Makefile
repair/globals.h
repair/init.c
repair/io.c [deleted file]
repair/phase1.c
repair/protos.h
repair/sb.c
repair/xfs_repair.c

index 81cd1c6411afbfc3f0e4f1a7f5b2724e66de00d2..6af8c0ec0aa447b7ee903c08df8c45cdbb65dc1c 100644 (file)
@@ -652,6 +652,7 @@ main(int argc, char **argv)
 
        memset(&xargs, 0, sizeof(xargs));
        xargs.notvolmsg = "oh no %s";
+       xargs.isdirect = LIBXFS_DIRECT;
        xargs.isreadonly = LIBXFS_ISREADONLY;
        xargs.notvolok = 1;
 
index 707cb383931bde2472558513fdbf1709c0557b4b..6ad5925eb82d11043a57f7fa03cd7500a8494f96 100644 (file)
@@ -68,6 +68,7 @@ typedef struct {
        char            *logname;       /* pathname of log "subvolume" */
        char            *rtname;        /* pathname of realtime "subvolume" */
        int             isreadonly;     /* filesystem is only read in applic */
+       int             isdirect;       /* we can attempt to use direct I/O */
        int             disfile;        /* data "subvolume" is a regular file */        int             dcreat;         /* try to create data subvolume */
        int             lisfile;        /* log "subvolume" is a regular file */
        int             lcreat;         /* try to create log subvolume */
@@ -98,6 +99,7 @@ typedef struct {
 #define LIBXFS_ISINACTIVE      0x0004  /* allow mounted only if mounted ro */
 #define LIBXFS_DANGEROUSLY     0x0008  /* repairing a device mounted ro    */
 #define LIBXFS_EXCLUSIVELY     0x0010  /* disallow other accesses (O_EXCL) */
+#define LIBXFS_DIRECT          0x0020  /* can use direct I/O, not buffered */
 
 extern char    *progname;
 extern int     libxfs_init (libxfs_init_t *);
@@ -106,8 +108,8 @@ extern int  libxfs_device_to_fd (dev_t);
 extern dev_t   libxfs_device_open (char *, int, int, int);
 extern void    libxfs_device_zero (dev_t, xfs_daddr_t, uint);
 extern void    libxfs_device_close (dev_t);
+extern int     libxfs_device_alignment (void);
 extern void    libxfs_report(FILE *);
-extern char    *libxfs_findrawpath(char *);
 
 /* check or write log footer: specify device, log size in blocks & uuid */
 typedef xfs_caddr_t (libxfs_get_block_t)(xfs_caddr_t, int, void *);
index 60780b049a55efa95e0907f6c9c3c468c0288fa4..59e47927174125a957ec2b9877e14bb42fd0739c 100644 (file)
@@ -92,17 +92,29 @@ platform_findsizes(char *path, int fd, long long *sz, int *bsz)
 int
 platform_aio_init(int aio_count)
 {
-       return (0);             /* aio/lio_listio not available */
+       return 0;               /* aio/lio_listio not available */
 }
 
 char *
 platform_findrawpath(char *path)
 {
-       return (path);
+       return path;
 }
 
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+       return path;
+}
+
+int
+platform_direct_blockdev(void)
+{
+       return 0;
+}
+
+int
+platform_align_blockdev(void)
 {
-       return sizeof(void *);
+       return (sizeof(void *));
 }
index 26ef3a10f095953b8700003af97cbd216e7d75be..a179fa8a6c547efe8e3dc7827404dedc9bceca60 100644 (file)
@@ -152,17 +152,29 @@ platform_findsizes(char *path, int fd, long long *sz, int *bsz)
 int
 platform_aio_init(int aio_count)
 {
-       return (0);             /* aio/lio_listio not available */
+       return 0;               /* aio/lio_listio not available */
 }
 
 char *
 platform_findrawpath(char *path)
 {
-       return (path);
+       return path;
 }
 
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+       return path;
+}
+
+int
+platform_direct_blockdev(void)
+{
+       return 0;
+}
+
+int
+platform_align_blockdev(void)
 {
-       return sizeof(void *);
+       return (sizeof(void *));
 }
index 212cb1eff50e14cd553a3e2905fa52ebfcfb6749..e5d4b985002aefd75bce252a14d598bc73f6310e 100644 (file)
@@ -20,9 +20,6 @@
 #include <sys/stat.h>
 #include "init.h"
 
-#define findrawpath(x) x
-#define findblockpath(x) x
-
 char *progname = "libxfs";     /* default, changed by each tool */
 
 struct cache *libxfs_icache;   /* global inode cache */
@@ -92,16 +89,22 @@ libxfs_device_open(char *path, int creat, int xflags, int setblksize)
 {
        dev_t           dev;
        int             fd, d, flags;
-       int             readonly, excl;
+       int             readonly, dio, excl;
        struct stat64   statb;
 
        readonly = (xflags & LIBXFS_ISREADONLY);
        excl = (xflags & LIBXFS_EXCLUSIVELY) && !creat;
+       dio = (xflags & LIBXFS_DIRECT) && !creat && platform_direct_blockdev();
 
+retry:
        flags = (readonly ? O_RDONLY : O_RDWR) | \
                (creat ? (O_CREAT|O_TRUNC) : 0) | \
+               (dio ? O_DIRECT : 0) | \
                (excl ? O_EXCL : 0);
+
        if ((fd = open(path, flags, 0666)) < 0) {
+               if (errno == EINVAL && --dio == 0)
+                       goto retry;
                fprintf(stderr, _("%s: cannot open %s: %s\n"),
                        progname, path, strerror(errno));
                exit(1);
@@ -181,13 +184,13 @@ check_open(char *path, int flags, char **rawfile, char **blockfile)
                perror(path);
                return 0;
        }
-       if (!(*rawfile = findrawpath(path))) {
+       if (!(*rawfile = platform_findrawpath(path))) {
                fprintf(stderr, _("%s: "
                                  "can't find a character device matching %s\n"),
                        progname, path);
                return 0;
        }
-       if (!(*blockfile = findblockpath(path))) {
+       if (!(*blockfile = platform_findblockpath(path))) {
                fprintf(stderr, _("%s: "
                                  "can't find a block device matching %s\n"),
                        progname, path);
@@ -235,7 +238,7 @@ libxfs_init(libxfs_init_t *a)
        (void)getcwd(curdir,MAXPATHLEN);
        needcd = 0;
        fd = -1;
-       flags = a->isreadonly;
+       flags = (a->isreadonly | a->isdirect);
 
        if (a->volname) {
                if(!check_open(a->volname,flags,&rawfile,&blockfile))
@@ -753,6 +756,12 @@ libxfs_destroy(void)
        cache_destroy(libxfs_bcache);
 }
 
+int
+libxfs_device_alignment(void)
+{
+       return platform_align_blockdev();
+}
+
 void
 libxfs_report(FILE *fp)
 {
@@ -766,9 +775,3 @@ libxfs_report(FILE *fp)
        c = asctime(localtime(&t));
        fprintf(fp, "%s", c);
 }
-
-char *
-libxfs_findrawpath(char *path)
-{
-       return platform_findrawpath(path);
-}
index 4fc62841c2d1c1f6c5fd5b4299c0ca298e2a0679..60e89902c4310518a318a83fdfa3981f431cd562 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
  * All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -28,6 +28,10 @@ extern void platform_findsizes (char *path, int fd, long long *sz, int *bsz);
 extern void platform_set_blocksize (int fd, char *path, int blocksize);
 extern void platform_flush_device (int fd, dev_t device);
 extern char *platform_findrawpath(char *path);
-extern int platform_aio_init(int aio_count);
-extern size_t platform_memalignment(void);
+extern char *platform_findrawpath (char *path);
+extern char *platform_findblockpath (char *path);
+extern int platform_direct_blockdev (void);
+extern int platform_align_blockdev (void);
+extern int platform_aio_init (int aio_count);
+
 #endif /* LIBXFS_INIT_H */
index d37a9783ae95fdc643d33551e317ace1f7c3ba72..b0f637aacd0819f9d9f7636116676669c1cb0c5d 100644 (file)
@@ -85,8 +85,20 @@ platform_findrawpath(char *path)
        return findrawpath(path);
 }
 
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+       return findblockpath(path);
+}
+
+int
+platform_direct_blockdev(void)
+{
+       return 0;
+}
+
+int
+platform_align_blockdev(void)
 {
-       return sizeof(void *);
+       return (sizeof(void *));
 }
index 8189049328685156f167b5afd143342127e6abf0..f2d975c4395b3d4e2444ecf508dbafaafac4f7b9 100644 (file)
@@ -27,6 +27,7 @@
 #include <sys/ioctl.h>
 
 extern char *progname;
+static int max_block_alignment;
 
 #ifndef BLKGETSIZE64
 # define BLKGETSIZE64  _IOR(0x12,114,size_t)
@@ -134,6 +135,8 @@ platform_findsizes(char *path, int fd, long long *sz, int *bsz)
        if ((st.st_mode & S_IFMT) == S_IFREG) {
                *sz = (long long)(st.st_size >> 9);
                *bsz = BBSIZE;
+               if (BBSIZE > max_block_alignment)
+                       max_block_alignment = BBSIZE;
                return;
        }
 
@@ -160,6 +163,8 @@ platform_findsizes(char *path, int fd, long long *sz, int *bsz)
                        progname, path, strerror(errno));
                *bsz = BBSIZE;
        }
+       if (*bsz > max_block_alignment)
+               max_block_alignment = *bsz;
 }
 
 int
@@ -178,7 +183,27 @@ platform_aio_init(int aio_count)
 char *
 platform_findrawpath(char *path)
 {
-       return (path);
+       return path;
+}
+
+char *
+platform_findblockpath(char *path)
+{
+       return path;
+}
+
+int
+platform_direct_blockdev(void)
+{
+       return 1;
+}
+
+int
+platform_align_blockdev(void)
+{
+       if (!max_block_alignment)
+               abort();
+       return max_block_alignment;
 }
 
 size_t
index d2e680f8b798ac62062a0008aebfd5f41445df1b..76e0f109a112e6fcde7684cc0886d6d6c51cb318 100644 (file)
 #define BDSTRAT_SIZE   (256 * 1024)
 #define min(x, y)      ((x) < (y) ? (x) : (y))
 
-static inline void *
-libxfs_memalign(size_t size)
-{
-       static size_t   memalignment;
-
-       if (!memalignment)
-               memalignment = platform_memalignment();
-       return memalign(memalignment, size);
-}
-
 void
 libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len)
 {
@@ -43,7 +33,7 @@ libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len)
        int             fd;
 
        zsize = min(BDSTRAT_SIZE, BBTOB(len));
-       if ((z = libxfs_memalign(zsize)) == NULL) {
+       if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) {
                fprintf(stderr,
                        _("%s: %s can't memalign %d bytes: %s\n"),
                        progname, __FUNCTION__, (int)zsize, strerror(errno));
@@ -268,7 +258,8 @@ libxfs_getbuf(dev_t device, xfs_daddr_t blkno, int len)
                bp->b_blkno = blkno;
                bp->b_bcount = bytes;
                bp->b_dev = device;
-               if (!(bp->b_addr = libxfs_memalign(bytes))) {
+               bp->b_addr = memalign(libxfs_device_alignment(), bytes);
+               if (!bp->b_addr) {
                        fprintf(stderr,
                                _("%s: %s can't memalign %d bytes: %s\n"),
                                progname, __FUNCTION__, (int)bytes,
index 419e6cdcc08215b9014a56db7b5d9a6964bdeb1f..1733110693df46148f451934dc1f9743db4e8fb1 100644 (file)
@@ -636,6 +636,7 @@ main(
        bzero(&xi, sizeof(xi));
        xi.notvolok = 1;
        xi.setblksize = 1;
+       xi.isdirect = LIBXFS_DIRECT;
        xi.isreadonly = LIBXFS_EXCLUSIVELY;
 
        while ((c = getopt(argc, argv, "b:d:i:l:L:n:Np:qr:s:CfV")) != EOF) {
index ae932045d76db3fc57b082a401b22a354ce4a389..b58ecbed11a39e193e87fd6ebe33df940c53d095 100644 (file)
@@ -85,7 +85,6 @@ XGETTEXTFILES =       \
                $(TOPDIR)/repair/incore_ext.c \
                $(TOPDIR)/repair/incore_ino.c \
                $(TOPDIR)/repair/init.c \
-               $(TOPDIR)/repair/io.c \
                $(TOPDIR)/repair/phase1.c \
                $(TOPDIR)/repair/phase2.c \
                $(TOPDIR)/repair/phase3.c \
index 5abe912b0adc16c1e77193ea8db069021d2fe942..f10442a29cf427b4ea20006c1b901f7da108c440 100644 (file)
@@ -13,7 +13,7 @@ HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h dinode.h dir.h \
 
 CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c dino_chunks.c \
        dinode.c dir.c dir2.c dir_stack.c globals.c incore.c \
-       incore_bmc.c init.c incore_ext.c incore_ino.c io.c phase1.c \
+       incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \
        phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c rt.c sb.c \
        prefetch.c scan.c versions.c xfs_repair.c
 
index 1e1ff51039398507ab9d8e1d874cb87a92e04d11..8194facfa79036ba2c02e034c9ec0d7cf57f5a13 100644 (file)
@@ -59,8 +59,6 @@
 #define        NUM_SBS                 8       /* max # of sbs to verify */
 #define NUM_AGH_SECTS          4       /* # of components in an ag header */
 
-#define        MEM_ALIGN               128     /* I/O buf alignment - a cache line */
-
 /*
  * secondary sb mask -- if the secondary sb feature bits has a
  * the partial sb mask bit set, then you depend on the fields
index 7c06f52d76af2c04aeb8cf757691a90081ca378c..75f1f746ad49081ff0884ed9552c120555ca142f 100644 (file)
@@ -130,6 +130,7 @@ xfs_init(libxfs_init_t *args)
        args->notvolok = 1;
        args->setblksize = !dangerously;
 
+       args->isdirect = LIBXFS_DIRECT;
        if (no_modify)
                args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE);
        else if (dangerously)
diff --git a/repair/io.c b/repair/io.c
deleted file mode 100644 (file)
index 8cf5e8f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <libxfs.h>
-#include "globals.h"
-#include "agheader.h"
-#include "protos.h"
-#include "err_protos.h"
-
-void
-io_init(void)
-{
-       /* open up filesystem device */
-
-       ASSERT(fs_name != NULL && *fs_name != '\0');
-
-       if ((fs_fd = open (fs_name, (no_modify? O_RDONLY : O_RDWR))) < 0)  {
-               do_error(_("couldn't open filesystem \"%s\"\n"), fs_name);
-       }
-}
index e782dd837856fb30e7c948907c2f947236022764..374e3202a25e82e6f889a0822ce2c20b287a9746 100644 (file)
@@ -35,7 +35,7 @@ alloc_ag_buf(int size)
 {
        char    *bp;
 
-       bp = (char *)memalign(MEM_ALIGN, size);
+       bp = (char *)memalign(libxfs_device_alignment(), size);
        if (!bp)
                do_error(_("could not allocate ag header buffer (%d bytes)\n"),
                        size);
@@ -55,8 +55,6 @@ phase1(xfs_mount_t *mp)
        char                    *ag_bp;
        int                     rval;
 
-       io_init();
-
        do_log(_("Phase 1 - find and verify superblock...\n"));
 
        primary_sb_modified = 0;
index 5a402789b9ea3ad6a4d4f796f6b43157ef26266f..a70c8f1593b29442904a852a6a180857fed3af1d 100644 (file)
@@ -17,7 +17,6 @@
  */
 
 void   xfs_init(libxfs_init_t *args);
-void   io_init(void);
 
 int    verify_sb(xfs_sb_t              *sb,
                int                     is_primary_sb);
index 3b78aa54a0db4f127847769e89d23fbbc6b4c57e..702d1cdb8a121c36b61584346f9179f47c130d04 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <libxfs.h>
+#include <libxlog.h>
 #include "agheader.h"
 #include "globals.h"
 #include "protos.h"
@@ -98,7 +99,7 @@ find_secondary_sb(xfs_sb_t *rsb)
 
        do_warn(_("\nattempting to find secondary superblock...\n"));
 
-       sb = (xfs_sb_t *) memalign(MEM_ALIGN, BSIZE);
+       sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
        if (!sb) {
                do_error(
        _("error finding secondary superblock -- failed to memalign buffer\n"));
@@ -117,11 +118,11 @@ find_secondary_sb(xfs_sb_t *rsb)
                /*
                 * read disk 1 MByte at a time.
                 */
-               if (lseek64(fs_fd, off, SEEK_SET) != off)  {
+               if (lseek64(x.dfd, off, SEEK_SET) != off)  {
                        done = 1;
                }
 
-               if (!done && (bsize = read(fs_fd, sb, BSIZE)) == 0)  {
+               if (!done && (bsize = read(x.dfd, sb, BSIZE)) == 0)  {
                        done = 1;
                }
 
@@ -451,19 +452,20 @@ write_primary_sb(xfs_sb_t *sbp, int size)
        if (no_modify)
                return;
 
-       if ((buf = calloc(size, 1)) == NULL) {
-               do_error(_("failed to malloc superblock buffer\n"));
+       if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) {
+               do_error(_("failed to memalign superblock buffer\n"));
                return;
        }
+       memset(buf, 0, size);
 
-       if (lseek64(fs_fd, 0LL, SEEK_SET) != 0LL) {
+       if (lseek64(x.dfd, 0LL, SEEK_SET) != 0LL) {
                free(buf);
                do_error(_("couldn't seek to offset 0 in filesystem\n"));
        }
 
        libxfs_xlate_sb(buf, sbp, -1, XFS_SB_ALL_BITS);
 
-       if (write(fs_fd, buf, size) != size) {
+       if (write(x.dfd, buf, size) != size) {
                free(buf);
                do_error(_("primary superblock write failed!\n"));
        }
@@ -480,27 +482,28 @@ get_sb(xfs_sb_t *sbp, xfs_off_t off, int size, xfs_agnumber_t agno)
        int error, rval;
        void *buf;
 
-       if ((buf = calloc(size, 1)) == NULL) {
+       if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) {
                do_error(
-       _("error reading superblock %u -- failed to malloc buffer\n"),
+       _("error reading superblock %u -- failed to memalign buffer\n"),
                        agno, off);
                exit(1);
        }
+       memset(buf, 0, size);
 
        /* try and read it first */
 
-       if (lseek64(fs_fd, off, SEEK_SET) != off)  {
+       if (lseek64(x.dfd, off, SEEK_SET) != off)  {
                do_warn(
        _("error reading superblock %u -- seek to offset %lld failed\n"),
                        agno, off);
                return(XR_EOF);
        }
 
-       if ((rval = read(fs_fd, buf, size)) != size)  {
+       if ((rval = read(x.dfd, buf, size)) != size)  {
                error = errno;
                do_warn(
        _("superblock read failed, offset %lld, size %d, ag %u, rval %d\n"),
-                       off, size, rval, agno);
+                       off, size, agno, rval);
                do_error("%s\n", strerror(error));
        }
        libxfs_xlate_sb(buf, sbp, 1, XFS_SB_ALL_BITS);
index 505e21e837cb8752f979c4ad6a443d7b228fbc95..20cf34718697fd3de8992a6fd0a1c5eab9db1887 100644 (file)
@@ -273,11 +273,6 @@ process_args(int argc, char **argv)
 
        if ((fs_name = argv[optind]) == NULL)
                usage();
-
-       if (!isa_file) {
-               if ((fs_name = libxfs_findrawpath(fs_name)) == NULL)
-                       do_error("couldn't find raw device for %s\n", fs_name);
-       }
 }
 
 void