]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Small xfs_io tweaks and fixes.
authorNathan Scott <nathans@sgi.com>
Fri, 5 Dec 2003 06:36:15 +0000 (06:36 +0000)
committerNathan Scott <nathans@sgi.com>
Fri, 5 Dec 2003 06:36:15 +0000 (06:36 +0000)
VERSION
debian/changelog
doc/CHANGES
io/command.h
io/input.c
io/input.h
io/pread.c
io/pwrite.c

diff --git a/VERSION b/VERSION
index b62db7f4a0324f0db918ab43bc2dc4ccad86cec3..b599fbaccf3781f319e02909354bbc4d097553a5 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -3,5 +3,5 @@
 #
 PKG_MAJOR=2
 PKG_MINOR=6
-PKG_REVISION=0
+PKG_REVISION=1
 PKG_BUILD=0
index abb851c8724caa9b2f592ab4c9e9f96d2e8cacb8..6eeca419888517876da215008b5bb1429eb6e662 100644 (file)
@@ -1,3 +1,9 @@
+xfsprogs (2.6.1-1) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Nathan Scott <nathans@debian.org>  Thu, 27 Nov 2003 13:47:17 +1100
+
 xfsprogs (2.6.0-1) unstable; urgency=low
 
   * New upstream release.
index 86747ad8b78b501eae6fbb81df733cb3e737ec18..fb803e8c56f8bb420a2029c5f7da9b3ee56709ea 100644 (file)
@@ -1,3 +1,8 @@
+xfsprogs-2.6.1 (27 November 2003)
+       - Human-friendly xfs_io read/write bsize specifications.
+       - Dump throughput and IOPs values after xfs_io reads/writes.
+       - Sync up user/kernel source in libxfs, libxlog and headers.
+
 xfsprogs-2.6.0 (28 October 2003)
        - Change to mkfs strategy for allocation group count and size
          default.  Scales significantly better for large filesystems.
index 69ee12b944c3cc0e0c33feb7829db7e2721e392b..9d291f1dbbf18b569dc0fc7c8888f064c31d55e7 100644 (file)
@@ -73,4 +73,5 @@ extern int            openfile(char *, xfs_fsop_geom_t *,
 extern void            *buffer;
 extern ssize_t         buffersize;
 extern int             alloc_buffer(ssize_t, unsigned int);
-extern int             read_buffer(int, off64_t, ssize_t, ssize_t *, int, int);
+extern int             read_buffer(int, off64_t, long long, long long *,
+                                       int, int);
index 3e0ed532870d3a086306348771f3c1415d053bd8..817b46666e628010f6a4025c8eecdfaf786e5cf8 100644 (file)
@@ -143,6 +143,13 @@ doneline(
        free(vec);
 }
 
+#define EXABYTES(x)    ((long long)(x) << 60)
+#define PETABYTES(x)   ((long long)(x) << 50)
+#define TERABYTES(x)   ((long long)(x) << 40)
+#define GIGABYTES(x)   ((long long)(x) << 30)
+#define MEGABYTES(x)   ((long long)(x) << 20)
+#define KILOBYTES(x)   ((long long)(x) << 10)
+
 long long
 cvtnum(
        int             blocksize,
@@ -163,14 +170,96 @@ cvtnum(
        if (*sp == 's' && sp[1] == '\0')
                return i * sectorsize;
        if (*sp == 'k' && sp[1] == '\0')
-               return 1024LL * i;
+               return KILOBYTES(i);
        if (*sp == 'm' && sp[1] == '\0')
-               return 1024LL * 1024LL * i;
+               return MEGABYTES(i);
        if (*sp == 'g' && sp[1] == '\0')
-               return 1024LL * 1024LL * 1024LL * i;
+               return GIGABYTES(i);
        if (*sp == 't' && sp[1] == '\0')
-               return 1024LL * 1024LL * 1024LL * 1024LL * i;
+               return TERABYTES(i);
        if (*sp == 'p' && sp[1] == '\0')
-               return 1024LL * 1024LL * 1024LL * 1024LL * 1024LL * i;
+               return PETABYTES(i);
+       if (*sp == 'e' && sp[1] == '\0')
+               return  EXABYTES(i);
        return -1LL;
 }
+
+#define TO_EXABYTES(x) ((x) / EXABYTES(1))
+#define TO_PETABYTES(x)        ((x) / PETABYTES(1))
+#define TO_TERABYTES(x)        ((x) / TERABYTES(1))
+#define TO_GIGABYTES(x)        ((x) / GIGABYTES(1))
+#define TO_MEGABYTES(x)        ((x) / MEGABYTES(1))
+#define TO_KILOBYTES(x)        ((x) / KILOBYTES(1))
+
+void
+cvtstr(
+       double          value,
+       char            *str,
+       size_t          size)
+{
+       char            *fmt;
+       int             precise;
+
+       precise = ((double)value * 1000 == (double)(int)value * 1000);
+
+       if (value >= EXABYTES(1)) {
+               fmt = precise ? "%.f EiB" : "%.3f EiB";
+               snprintf(str, size, fmt, TO_EXABYTES(value));
+       } else if (value >= PETABYTES(1)) {
+               fmt = precise ? "%.f PiB" : "%.3f PiB";
+               snprintf(str, size, fmt, TO_PETABYTES(value));
+       } else if (value >= TERABYTES(1)) {
+               fmt = precise ? "%.f TiB" : "%.3f TiB";
+               snprintf(str, size, fmt, TO_TERABYTES(value));
+       } else if (value >= GIGABYTES(1)) {
+               fmt = precise ? "%.f GiB" : "%.3f GiB";
+               snprintf(str, size, fmt, TO_GIGABYTES(value));
+       } else if (value >= MEGABYTES(1)) {
+               fmt = precise ? "%.f MiB" : "%.3f MiB";
+               snprintf(str, size, fmt, TO_MEGABYTES(value));
+       } else if (value >= KILOBYTES(1)) {
+               fmt = precise ? "%.f KiB" : "%.3f KiB";
+               snprintf(str, size, fmt, TO_KILOBYTES(value));
+       } else {
+               snprintf(str, size, "%f bytes", value);
+       }
+}
+
+struct timeval
+tsub(struct timeval t1, struct timeval t2)
+{
+       t1.tv_usec -= t2.tv_usec;
+       if (t1.tv_usec < 0) {
+               t1.tv_usec += 1000000;
+               t1.tv_sec--;
+       }
+       t1.tv_sec -= t2.tv_sec;
+       return t1;
+}
+
+double
+tdiv(double value, struct timeval tv)
+{
+       return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
+}
+
+#define HOURS(sec)     ((sec) / (60 * 60))
+#define MINUTES(sec)   (((sec) % (60 * 60)) / 60)
+#define SECONDS(sec)   ((sec) % 60)
+
+void
+timestr(
+       struct timeval  *tv,
+       char            *ts,
+       size_t          size)
+{
+       if (!tv->tv_sec)
+               snprintf(ts, size, "%.4f sec",
+                       ((double) tv->tv_usec / 1000000.0));
+       else
+               snprintf(ts, size, "%02u:%02u:%02u.%-u",
+                       (unsigned int) HOURS(tv->tv_sec),
+                       (unsigned int) MINUTES(tv->tv_sec),
+                       (unsigned int) SECONDS(tv->tv_sec),
+                       (unsigned int) tv->tv_usec);
+}
index 1121dcfb98c68785383b5df6d07ef78cc1ac58c7..d5153621737d54736f794e5c399363184193a257 100644 (file)
@@ -34,4 +34,8 @@ extern char   **breakline(char *input, int *count);
 extern void    doneline(char *input, char **vec);
 extern char    *fetchline(void);
 extern long long cvtnum(int blocksize, int sectorsize, char *s);
+extern void    cvtstr(double value, char *str, size_t sz);
+extern struct timeval tsub(struct timeval t1, struct timeval t2);
+extern double  tdiv(double value, struct timeval tv);
+extern void    timestr(struct timeval *tv, char *str, size_t sz);
 
index f4eea9a18974e083bb107381254f13694e78801f..579c0096792540fbe7eca5bf6271d5f78104a94d 100644 (file)
@@ -106,31 +106,34 @@ int
 read_buffer(
        int             fd,
        off64_t         offset,
-       ssize_t         count,
-       ssize_t         *total,
+       long long       count,
+       long long       *total,
        int             verbose,
        int             onlyone)
 {
-       ssize_t         bytes;
+       ssize_t         bytes, bytes_requested;
+       int             ops = 0;
 
        *total = 0;
        while (count > 0) {
-               bytes = pread64(fd, buffer, min(count,buffersize), offset);
+               bytes_requested = min(count, buffersize);
+               bytes = pread64(fd, buffer, bytes_requested, offset);
                if (bytes == 0)
                        break;
                if (bytes < 0) {
                        perror("pread64");
-                       return 0;
+                       return -1;
                }
+               ops++;
                if (verbose)
                        dump_buffer(offset, bytes);
                *total += bytes;
-               if (onlyone || bytes < count)
+               if (onlyone || bytes < bytes_requested)
                        break;
                offset += bytes;
                count -= bytes;
        }
-       return 1;
+       return ops;
 }
 
 static int
@@ -139,17 +142,18 @@ pread_f(
        char            **argv)
 {
        off64_t         offset;
-       ssize_t         count, total;
+       long long       count, total;
        unsigned int    bsize = 4096;
-       char            *sp;
+       struct timeval  t1, t2;
+       char            s1[64], s2[64], ts[64];
        int             vflag = 0;
        int             c;
 
        while ((c = getopt(argc, argv, "b:v")) != EOF) {
                switch (c) {
                case 'b':
-                       bsize = strtoul(optarg, &sp, 0);
-                       if (!sp || sp == optarg) {
+                       bsize = cvtnum(fgeom.blocksize, fgeom.sectsize, optarg);
+                       if (bsize < 0) {
                                printf(_("non-numeric bsize -- %s\n"), optarg);
                                return 0;
                        }
@@ -172,7 +176,7 @@ pread_f(
                return 0;
        }
        optind++;
-       count = (ssize_t)cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]);
+       count = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]);
        if (count < 0) {
                printf(_("non-numeric length argument -- %s\n"), argv[optind]);
                return 0;
@@ -181,11 +185,19 @@ pread_f(
        if (!alloc_buffer(bsize, 0xabababab))
                return 0;
 
-       if (!read_buffer(fdesc, offset, count, &total, vflag, 0))
+       gettimeofday(&t1, NULL);
+       if ((c = read_buffer(fdesc, offset, count, &total, vflag, 0)) < 0)
                return 0;
+       gettimeofday(&t2, NULL);
+       t2 = tsub(t2, t1);
 
        printf(_("read %ld/%ld bytes at offset %lld\n"),
                (long)total, (long)count, (long long)offset);
+       cvtstr((double)total, s1, sizeof(s1));
+       cvtstr(tdiv((double)total, t2), s2, sizeof(s2));
+       timestr(&t2, ts, sizeof(ts));
+       printf(_("---- %s, %d ops; %s (%s/sec and %.f ops/sec)\n"),
+               s1, c, ts, s2, tdiv((double)c, t2));
        return 0;
 }
 
index 6d4079e726cfe3cba1745d6ee8ad751528bd1f53..5848611f7b0ecdf76c1a7e42f9f7d859385e47de 100644 (file)
@@ -61,35 +61,38 @@ pwrite_help(void)
 static int
 write_buffer(
        off64_t         offset,
-       ssize_t         count,
+       long long       count,
        ssize_t         bs,
        int             fd,
        off64_t         skip,
-       ssize_t         *total)
+       long long       *total)
 {
-       ssize_t         bytes, bytes_requested, itotal = min(bs, count);
+       ssize_t         bytes, bytes_requested;
+       long long       bar = min(bs, count);
+       int             ops = 0;
 
        *total = 0;
        while (count > 0) {
                if (fd > 0) {   /* input file given, read buffer first */
-                       if (!read_buffer(fd, skip + *total, bs, &itotal, 0, 1))
+                       if (read_buffer(fd, skip + *total, bs, &bar, 0, 1) < 0)
                                break;
                }
-               bytes_requested = min(itotal, count);
+               bytes_requested = min(bar, count);
                bytes = pwrite64(fdesc, buffer, bytes_requested, offset);
                if (bytes == 0)
                        break;
                if (bytes < 0) {
                        perror("pwrite64");
-                       return 0;
+                       return -1;
                }
+               ops++;
                *total += bytes;
                if (bytes < bytes_requested)
                        break;
                offset += bytes;
                count -= bytes;
        }
-       return 1;
+       return ops;
 }
 
 static int
@@ -98,17 +101,19 @@ pwrite_f(
        char            **argv)
 {
        off64_t         offset, skip = 0;
-       ssize_t         count, total;
+       long long       count, total;
        unsigned int    seed = 0xcdcdcdcd;
        unsigned int    bsize = 4096;
+       struct timeval  t1, t2;
+       char            s1[64], s2[64], ts[64];
        char            *sp, *infile = NULL;
        int             c, fd = -1, dflag = 0;
 
        while ((c = getopt(argc, argv, "b:df:i:s:S:")) != EOF) {
                switch (c) {
                case 'b':
-                       bsize = strtoul(optarg, &sp, 0);
-                       if (!sp || sp == optarg) {
+                       bsize = cvtnum(fgeom.blocksize, fgeom.sectsize, optarg);
+                       if (bsize < 0) {
                                printf(_("non-numeric bsize -- %s\n"), optarg);
                                return 0;
                        }
@@ -149,7 +154,7 @@ pwrite_f(
                return 0;
        }
        optind++;
-       count = (ssize_t)cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]);
+       count = cvtnum(fgeom.blocksize, fgeom.sectsize, argv[optind]);
        if (count < 0) {
                printf(_("non-numeric length argument -- %s\n"), argv[optind]);
                return 0;
@@ -162,12 +167,21 @@ pwrite_f(
            ((fd = openfile(infile, NULL, 0, 0, dflag, 1, 0, 0, 0)) < 0))
                return 0;
 
-       if (!write_buffer(offset, count, bsize, fd, skip, &total)) {
+       gettimeofday(&t1, NULL);
+       if ((c = write_buffer(offset, count, bsize, fd, skip, &total)) < 0) {
                close(fd);
                return 0;
        }
+       gettimeofday(&t2, NULL);
+       t2 = tsub(t2, t1);
+
        printf(_("wrote %ld/%ld bytes at offset %lld\n"),
                (long)total, (long)count, (long long)offset);
+       cvtstr((double)total, s1, sizeof(s1));
+       cvtstr(tdiv((double)total, t2), s2, sizeof(s2));
+       timestr(&t2, ts, sizeof(ts));
+       printf(_("----- %s, %d ops; %s (%s/sec and %.f ops/sec)\n"),
+               s1, c, ts, s2, tdiv((double)c, t2));
        close(fd);
        return 0;
 }