Hello community,

here is the log from the commit of package f3 for openSUSE:Factory checked in 
at 2020-05-26 17:21:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/f3 (Old)
 and      /work/SRC/openSUSE:Factory/.f3.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "f3"

Tue May 26 17:21:00 2020 rev:8 rq:807957 version:7.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/f3/f3.changes    2020-02-05 19:41:34.703264163 
+0100
+++ /work/SRC/openSUSE:Factory/.f3.new.2738/f3.changes  2020-05-26 
17:21:13.588220677 +0200
@@ -1,0 +2,9 @@
+Wed May 20 11:50:43 UTC 2020 - Olav Reinert <[email protected]>
+
+- update to 7.2:
+    * f3write: keep up with extremely fast NVM drives (issue #117)
+    * f3write: improve measurement of write speed (issue #102)
+    * f3write: handle rare assetion failure (issue #111)
+    * f3probe: handle rare assetion failure (issue #82)
+
+-------------------------------------------------------------------

Old:
----
  f3-7.1.tar.gz

New:
----
  f3-7.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ f3.spec ++++++
--- /var/tmp/diff_new_pack.tCUEN0/_old  2020-05-26 17:21:14.088221752 +0200
+++ /var/tmp/diff_new_pack.tCUEN0/_new  2020-05-26 17:21:14.092221761 +0200
@@ -17,14 +17,15 @@
 
 
 Name:           f3
-Version:        7.1
+Version:        7.2
 Release:        0
 Summary:        Fight Flash Fraud / Fight Fake Flash
 License:        GPL-3.0-only
 Group:          Hardware/Other
 URL:            http://oss.digirati.com.br/f3/
 Source:         
https://github.com/AltraMayor/f3/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
-BuildRequires:  parted-devel
+BuildRequires:  pkgconfig
+BuildRequires:  pkgconfig(libparted)
 BuildRequires:  pkgconfig(libudev)
 
 %description
@@ -50,7 +51,7 @@
 %else
 export CFLAGS="%{optflags}"
 %endif
-make %{?_smp_mflags} all extra
+%make_build all extra
 
 mkdir examples
 mv log-f3wr f3write.h2w examples
@@ -67,7 +68,7 @@
 %{_bindir}/f3probe
 %{_bindir}/f3brew
 %{_bindir}/f3fix
-%{_mandir}/man1/f3read.1%{ext_man}
-%{_mandir}/man1/f3write.1%{ext_man}
+%{_mandir}/man1/f3read.1%{?ext_man}
+%{_mandir}/man1/f3write.1%{?ext_man}
 
 %changelog

++++++ f3-7.1.tar.gz -> f3-7.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/README.rst new/f3-7.2/README.rst
--- old/f3-7.1/README.rst       2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/README.rst       2019-06-19 20:43:19.000000000 +0200
@@ -63,7 +63,7 @@
 `here <https://github.com/AltraMayor/f3/releases>`__. The
 following command uncompresses the files::
 
-    $ unzip f3-7.1.zip
+    $ unzip f3-7.2.zip
 
 
 Compile stable software on Linux or FreeBSD
@@ -135,7 +135,7 @@
 
      /usr/bin/ruby -e "$(curl -fsSL 
https://raw.githubusercontent.com/Homebrew/install/master/install)"
 
-   See http://brew.sh/ for details.
+   See https://brew.sh/ for details.
 
    MacPorts: https://www.macports.org/install.php
 
@@ -209,7 +209,7 @@
 graphical user interfaces (GUIs) available for F3:
 
 `F3 QT <https://github.com/zwpwjwtz/f3-qt>`__ is a Linux GUI that uses
-QT. F3 QT supports ``f3write``, ``f3read``, and ``f3probe``. Author:
+QT. F3 QT supports ``f3write``, ``f3read``, ``f3probe``, and ``f3fix``. Author:
 Tianze.
 
 `F3 X <https://github.com/insidegui/F3X>`__ is a OS X GUI that uses
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/changelog new/f3-7.2/changelog
--- old/f3-7.1/changelog        2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/changelog        2019-06-19 20:43:19.000000000 +0200
@@ -1,3 +1,10 @@
+Version 7.2 - Jun 19, 2019
+
+    * f3write: keep up with extremely fast NVM drives (issue #117)
+    * f3write: improve measurement of write speed (issue #102)
+    * f3write: handle rare assetion failure (issue #111)
+    * f3probe: handle rare assetion failure (issue #82)
+
 Version 7.1 - Jul 27, 2018
 
     * fix compilation issues on non-Linux OSs
@@ -58,7 +65,7 @@
     * f3write now reports proper progress.
     * added progress printout in f3read.
     * improved precision of speed measurements.
-    * formated code following Linux's coding style.
+    * formatted code following Linux's coding style.
 
 Version 1.1.3 - Sep 21, 2010
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/doc/conf.py new/f3-7.2/doc/conf.py
--- old/f3-7.1/doc/conf.py      2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/doc/conf.py      2019-06-19 20:43:19.000000000 +0200
@@ -58,9 +58,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '7.1'
+version = '7.2'
 # The full version, including alpha/beta/rc tags.
-release = '7.1'
+release = '7.2'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/doc/contribute.rst 
new/f3-7.2/doc/contribute.rst
--- old/f3-7.1/doc/contribute.rst       2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/doc/contribute.rst       2019-06-19 20:43:19.000000000 +0200
@@ -14,7 +14,7 @@
    F3 on GitHub. The larger the number of stars a project has, the more
    confident new users are to try it out.
 -  If you know a journalist, or are one, suggest to him or her writing
-   an article about fake flash. The media has not been corvering this
+   an article about fake flash. The media has not been covering this
    subject, and having more users aware that fake flash exists will make
    counterfeiters' life harder.
 -  If you own fake flash, consider donating them to me. I've been
@@ -45,9 +45,9 @@
    well, so people can reach out to you directly.
 -  If you know how to code a graphic user interface, please create one
    for the platforms you can. This would increase the number of users
-   that, in turn, would win ground againt the counterfeiters. I'll add a
+   that, in turn, would win ground against the counterfeiters. I'll add a
    link to your application on this page.
--  Tell your frinds about F3, teach them how to use it, publish a video
+-  Tell your friends about F3, teach them how to use it, publish a video
    about F3, find ways to help me to better organize our efforts, spread
    the word, ask for your money back when you buy a fake drive, etc.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/doc/history.rst new/f3-7.2/doc/history.rst
--- old/f3-7.1/doc/history.rst  2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/doc/history.rst  2019-06-19 20:43:19.000000000 +0200
@@ -5,7 +5,7 @@
 Android phone back in 2010, and found out that this card always fails
 when one fills it up. Googling about this issue, I arrived at the blogs
 `Fight Flash Fraud <https://fightflashfraud.wordpress.com/>`__ and
-`SOSFakeFlash <https://sosfakeflash.wordpress.com/>`__, which recomend
+`SOSFakeFlash <https://sosfakeflash.wordpress.com/>`__, which recommend
 the software H2testw (see
 `here 
<https://fightflashfraud.wordpress.com/2008/11/24/h2testw-gold-standard-in-detecting-fake-capacity-flash/>`__
 or
@@ -34,7 +34,7 @@
 
 Starting at version 2.0, F3 supports the platform Mac. Mac users may
 want to check out Thijs Kuipers'
-`page 
<http://www.broes.nl/2012/08/verify-the-integrity-of-a-flash-sd-card-on-a-mac/>`__
+`page 
<https://www.broes.nl/2012/08/verify-the-integrity-of-a-flash-sd-card-on-a-mac/>`__
 for help.
 
 Starting at version 3.0, F3 supports the platform Windows/Cygwin, and
@@ -53,7 +53,7 @@
 Linux only. Linux users may want to check out Vasiliy Kaygorodov's
 `page 
<https://serverissues.com/blog/2015/12/12/finding-out-chinese-flash-disk-slash-sdhc-card-real-size/>`__
 or Ahmed Essam's
-`page 
<http://ahmedspace.com/linux-how-to-fix-a-flash-memory-corrupting-files/>`__
+`page 
<https://ahmedspace.com/how-to-recover-a-corrupted-flash-memory-using-f3-tools-under-linux/>`__
 for help.
 
 Starting at version 7.0, ``f3probe``, ``f3fix``, and ``f3brew`` are stable.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/doc/usage.rst new/f3-7.2/doc/usage.rst
--- old/f3-7.1/doc/usage.rst    2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/doc/usage.rst    2019-06-19 20:43:19.000000000 +0200
@@ -341,7 +341,7 @@
 the drive. One can estimate the size of this cache as follows: 523920 \*
 512B ~ 256MB.
 
-Tom Metro once ran ``f3write`` on a 16GB flash drive formated with ext2
+Tom Metro once ran ``f3write`` on a 16GB flash drive formatted with ext2
 file system, and obtained puzzling free space at the end of
 ``f3write``'s output:
 
@@ -371,7 +371,7 @@
 special purposes. So they don't allow ``f3write`` to use that reserved
 space. It's mostly safe to ignore that free space. If one wants to use
 all space possible, there're two options: (1) using a file system that
-doesn't reserve space (e.g FAT), or (2) reducing the reserved space. How
+doesn't reserve space (e.g. FAT), or (2) reducing the reserved space. How
 to go for the second option depends on the used file system. The
 `page 
<http://www.microhowto.info/howto/reduce_the_space_reserved_for_root_on_an_ext2_ext3_or_ext4_filesystem.html>`__
 explains how to reduce the reserved space on ext2, ext3, and ext4 file
@@ -386,14 +386,14 @@
 being 2^30 bytes, whereas the rest of the industry assumes that 1GB is
 equal to 10^9 bytes. Some people use GiB for the first definition, but
 its use is not universal, and some users even get confused when they see
-this unit. With this information in mind, the mistery is easily solved:
+this unit. With this information in mind, the mystery is easily solved:
 14.63GiB \* 2^30 / 10^9 = 15.71GB.
 
 When Art Gibbens tested a flash card hosted in a camera connected to his
 Linux box, at some point F3 didn't show progress, and could not be
 killed. After a reboot, the card was read only. Using an adapter to
 connect his card directly to his machine, he recreated the partition of
-the card, and successfully ran F3 with the card in the adpater. Thus,
+the card, and successfully ran F3 with the card in the adapter. Thus,
 Art's experience is a good warning if you're testing your card in a
 device other than an adapter. Please, don't take it as a bug of F3. I'm
 aware of only two things that can make a process "survive" a kill
@@ -415,7 +415,7 @@
 access to the device being tested, not the file system in it; (2)
 hardware may fail, but it won't lie. The first assumption implies that
 one likely needs root's rights to run dosfsck, what is just a small
-incovenience for simple uses. The second assumption is troublesome
+inconvenience for simple uses. The second assumption is troublesome
 because a fake card may be able to persuade dosfsck(8) to report it's
 fine, or not report the whole problem, or give users the illusion the
 memory card was fixed when it wasn't. I singled dosfsck(8) out because
@@ -486,14 +486,14 @@
 capacity grows, the time to test these newer drives becomes so painful
 that one rarely runs H2testw's algorithm on a whole drive, but only a
 fraction of it. See question "Why test only 25% or 32GB?" on `this
-FAQ 
<http://www.ebay.com/gds/All-About-Fake-Flash-Drives-2013-/10000000177553258/g.html>`__
+FAQ 
<https://web.archive.org/web/20180318154936/https://www.ebay.com/gds/All-About-Fake-Flash-Drives-2013-/10000000177553258/g.html>`__
 for a defense of this approach.
 
 The problem with this approach is that drives are still getting bigger,
-and conterfeiters may, in the future, be able to profit with fake drives
+and counterfeiters may, in the future, be able to profit with fake drives
 whose real capacity are large enough to fool these partial tests. This
 problem is not new. For example, Steve Si implemented
-`FakeFlashTest.exe 
<http://www.rmprepusb.com/tutorials/-fake-usb-flash-memory-drives>`__,
+`FakeFlashTest.exe 
<https://www.rmprepusb.com/tutorials/-fake-usb-flash-memory-drives>`__,
 which has successfully reduced the amount of time to test drives, and is
 still able to give a good estimate of the real size of fake drives. Yet,
 `FakeFlashTest.exe's
@@ -558,10 +558,10 @@
 messing your machine up. If you don't have root access, you can't use
 ``f3probe``; use ``f3write/f3read`` in this case. The use example below
 helps with the second requirement, but don't forget that you are the one
-responsable for doing it right!
+responsible for doing it right!
 
 The command lsblk(8) is handy to find the block device of the drive. In
-the example below, which I got running lsblk on my laptop, an experient
+the example below, which I got running lsblk on my laptop, an experienced
 user can quickly identify that my flash drive that is mounted at
 "/media/michel/A902-D705" is block device "/dev/sdb". If you don't have
 much experience, you may want to run lsblk before connecting the drive
@@ -588,7 +588,7 @@
 If you get confused between "sdb" and "sdb1", don't worry, ``f3probe``
 will report the mistake and point out the proper one. However, I cannot
 emphasize it enough, you MUST identify the correct drive. If I had
-chosen "sda", ``f3probe`` may have messied my computer. Once the device
+chosen "sda", ``f3probe`` may have messed my computer. Once the device
 is chosen, just prefix it with "/dev/" to obtain its full name.
 
 Once you have carefully identified the device, you run ``f3probe`` like
@@ -598,7 +598,7 @@
 
     $ sudo ./f3probe --destructive --time-ops /dev/sdb
     [sudo] password for michel: 
-    F3 probe 7.1
+    F3 probe 7.2
     Copyright (C) 2010 Digirati Internet LTDA.
     This is free software; see the source for copying conditions.
 
@@ -640,7 +640,7 @@
 crashes, the conservative mode won't work. Moreover, depending on the
 fake drive, the conservative mode may not recover the drive to its exact
 original state. In case you are running ``f3probe`` on a
-memory-constrainted computer (e.g. an old Raspberry Pi board), you can
+memory-constrained computer (e.g. an old Raspberry Pi board), you can
 still run it in conservative mode reducing the amount of memory needed
 with option "--min-memory". If you don't have memory to test a large
 drive even using option "--min-memory", you need to use option
@@ -658,7 +658,7 @@
 The probe time of 1'13" includes the time to run the probe algorithm,
 take measurements, and the time to perform all operations on the drive.
 But it doesn't include the time to recover the saved blocks (if this
-feature is enabled). Therefore, the test would take rougthly another
+feature is enabled). Therefore, the test would take roughly another
 55.48s (i.e. total write time) to write all blocks back to the drive. As
 some will notice, the time to perform all operations on the drive is
 what dominates the probe time: 472.1ms + 55.48s + 17.88s = 1'13". It's
@@ -673,7 +673,7 @@
 
     $ sudo ./f3probe --time-ops /dev/sdc
     [sudo] password for michel: 
-    F3 probe 7.1
+    F3 probe 7.2
     Copyright (C) 2010 Digirati Internet LTDA.
     This is free software; see the source for copying conditions.
 
@@ -733,7 +733,7 @@
 ::
 
     $ sudo ./f3fix --last-sec=16477878 /dev/sdb
-    F3 fix 7.1
+    F3 fix 7.2
     Copyright (C) 2010 Digirati Internet LTDA.
     This is free software; see the source for copying conditions.
 
@@ -811,7 +811,7 @@
 
 If you get some sectors corrupted, repeat the ``f3write/f3read`` test.
 Some drives recover from these failures on a second full write cycle.
-However, if the corrupeted sectors persist, the drive is junk because
+However, if the corrupted sectors persist, the drive is junk because
 not only is it a fake drive, but its real memory is already failing.
 
 Good luck!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/f3brew.c new/f3-7.2/f3brew.c
--- old/f3-7.1/f3brew.c 2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/f3brew.c 2019-06-19 20:43:19.000000000 +0200
@@ -17,6 +17,9 @@
 /* Arguments. */
 static char adoc[] = "<DISK_DEV>";
 
+/* The capital "E" in "REad" in the string below is not a typo.
+ * It shows from where the name B-RE-W comes.
+ */
 static char doc[] = "F3 Block REad and Write -- assess the media of "
        "a block device writing blocks, resetting the drive, and "
        "reading the blocks back";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/f3probe.c new/f3-7.2/f3probe.c
--- old/f3-7.1/f3probe.c        2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/f3probe.c        2019-06-19 20:43:19.000000000 +0200
@@ -508,7 +508,7 @@
        }
 
        free((void *)final_dev_filename);
-       return 0;
+       return fake_type == FKTY_GOOD ? 0 : 100 + fake_type;
 }
 
 int main(int argc, char **argv)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/f3read.1 new/f3-7.2/f3read.1
--- old/f3-7.1/f3read.1 2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/f3read.1 2019-06-19 20:43:19.000000000 +0200
@@ -1,5 +1,5 @@
 .\"Text automatically generated by txt2man
-.TH F3 "1"  "July 2018" "F3 7.1" "test real flash memory capacity"
+.TH F3 "1"  "June 2019" "F3 7.2" "test real flash memory capacity"
 .SH NAME
 \fBf3write, f3read \fP- test real flash memory capacity
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/f3write.c new/f3-7.2/f3write.c
--- old/f3-7.1/f3write.c        2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/f3write.c        2019-06-19 20:43:19.000000000 +0200
@@ -143,20 +143,20 @@
        uint64_t        total_written;
        /* If true, show progress. */
        int             progress;
-       /* Writing rate in bytes. */
+       /* Block size in bytes. */
        int             block_size;
+       /* Delay intended between measurements in miliseconds. */
+       unsigned int    delay_ms;
        /* Increment to apply to @blocks_per_delay. */
-       int             step;
+       int64_t         step;
        /* Blocks to write before measurement. */
-       int             blocks_per_delay;
-       /* Delay in miliseconds. */
-       int             delay_ms;
+       int64_t         blocks_per_delay;
        /* Maximum write rate in bytes per second. */
        double          max_write_rate;
-       /* Number of measurements after reaching FW_STEADY state. */
-       uint64_t        measurements;
        /* Number of measured blocks. */
        uint64_t        measured_blocks;
+       /* Measured time. */
+       uint64_t        measured_time_ms;
        /* State. */
        enum {FW_INC, FW_DEC, FW_SEARCH, FW_STEADY} state;
        /* Number of characters to erase before printing out progress. */
@@ -167,11 +167,11 @@
         */
 
        /* Number of blocks written since last measurement. */
-       int             written_blocks;
+       int64_t         written_blocks;
        /* Range of blocks_per_delay while in FW_SEARCH state. */
-       int             bpd1, bpd2;
+       int64_t         bpd1, bpd2;
        /* Time measurements. */
-       struct timeval  t1, t2;
+       struct timeval  t1;
 };
 
 static inline void move_to_inc_at_start(struct flow *fw)
@@ -194,8 +194,8 @@
        fw->delay_ms            = 1000; /* 1s           */
        fw->max_write_rate      = max_write_rate <= 0
                ? DBL_MAX : max_write_rate * 1024.;
-       fw->measurements        = 0;
        fw->measured_blocks     = 0;
+       fw->measured_time_ms    = 0;
        fw->erase               = 0;
        assert(fw->block_size > 0);
        assert(fw->block_size % SECTOR_SIZE == 0);
@@ -226,11 +226,17 @@
        repeat_ch('\b', count);
 }
 
+static inline double get_avg_speed_given_time(struct flow *fw,
+       uint64_t total_time_ms)
+{
+       return (double)(fw->measured_blocks * fw->block_size * 1000) /
+               total_time_ms;
+}
+
 /* Average writing speed in byte/s. */
 static inline double get_avg_speed(struct flow *fw)
 {
-       return  (double)(fw->measured_blocks * fw->block_size * 1000) /
-               (double)(fw->measurements * fw->delay_ms);
+       return get_avg_speed_given_time(fw, fw->measured_time_ms);
 }
 
 static int pr_time(double sec)
@@ -270,19 +276,12 @@
        return tot + c;
 }
 
-static inline void update_mean(struct flow *fw)
-{
-       fw->measurements++;
-       fw->measured_blocks += fw->written_blocks;
-}
-
 static inline void move_to_steady(struct flow *fw)
 {
-       update_mean(fw);
        fw->state = FW_STEADY;
 }
 
-static void move_to_search(struct flow *fw, int bpd1, int bpd2)
+static void move_to_search(struct flow *fw, int64_t bpd1, int64_t bpd2)
 {
        assert(bpd1 > 0);
        assert(bpd2 >= bpd1);
@@ -337,15 +336,15 @@
        long delay, double inst_speed)
 {
        /* We use logical and here to enforce both limist. */
-       return delay < fw->delay_ms && inst_speed < fw->max_write_rate;
+       return delay <= fw->delay_ms && inst_speed < fw->max_write_rate;
 }
 
 static int measure(int fd, struct flow *fw, ssize_t written)
 {
-       long delay;
-       div_t result = div(written, fw->block_size);
-       double inst_speed;
-       bool slow_down = false;
+       ldiv_t result = ldiv(written, fw->block_size);
+       struct timeval t2;
+       int64_t delay;
+       double bytes_k, inst_speed;
 
        assert(result.rem == 0);
        fw->written_blocks += result.quot;
@@ -357,14 +356,46 @@
        if (fdatasync(fd) < 0)
                return -1; /* Caller can read errno(3). */
 
-       assert(!gettimeofday(&fw->t2, NULL));
        /* Help the kernel to help us. */
        assert(!posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED));
-       delay = delay_ms(&fw->t1, &fw->t2);
+
+       assert(!gettimeofday(&t2, NULL));
+       delay = delay_ms(&fw->t1, &t2);
 
        /* Instantaneous speed in bytes per second. */
-       inst_speed = (double)fw->blocks_per_delay * fw->block_size * 1000 /
-               fw->delay_ms;
+       bytes_k = fw->blocks_per_delay * fw->block_size * 1000.0;
+       inst_speed = bytes_k / delay;
+
+       if (delay < fw->delay_ms && inst_speed > fw->max_write_rate) {
+               /* Wait until inst_speed == fw->max_write_rate (if possible). */
+               double wait_ms = round((bytes_k - delay * fw->max_write_rate)
+                       / fw->max_write_rate);
+
+                if (wait_ms < 0) {
+                       /* Wait what is possible. */
+                       wait_ms = fw->delay_ms - delay;
+               } else if (delay + wait_ms < fw->delay_ms) {
+                       /* wait_ms is not the largest possible value, so
+                        * force the flow algorithm to keep increasing it.
+                        * Otherwise, the delay to print progress may be
+                        * too small.
+                        */
+                       wait_ms++;
+               }
+
+               if (wait_ms > 0) {
+                       /* Slow down. */
+                       assert(!usleep(wait_ms * 1000));
+
+                       /* Adjust measurements. */
+                       delay += wait_ms;
+                       inst_speed = bytes_k / delay;
+               }
+       }
+
+       /* Update mean. */
+       fw->measured_blocks += fw->written_blocks;
+       fw->measured_time_ms += delay;
 
        switch (fw->state) {
        case FW_INC:
@@ -404,24 +435,18 @@
                        move_to_steady(fw);
                break;
 
-       case FW_STEADY:
-               update_mean(fw);
-
+       case FW_STEADY: {
                if (delay <= fw->delay_ms) {
                        if (inst_speed < fw->max_write_rate) {
                                move_to_inc(fw);
-                       } if (inst_speed > fw->max_write_rate) {
+                       } else if (inst_speed > fw->max_write_rate) {
                                move_to_dec(fw);
-                       } else {
-                               /* Since we are already writing at
-                                * maximum allowed rate, wait until next cycle.
-                                */
-                               slow_down = true;
                        }
                } else if (fw->blocks_per_delay > 1) {
                        move_to_dec(fw);
                }
                break;
+       }
 
        default:
                assert(0);
@@ -441,7 +466,7 @@
                fw->erase = printf("%.2f%% -- %.2f %s/s",
                        percent, inst_speed, unit);
                assert(fw->erase > 0);
-               if (fw->measurements > 0)
+               if (fw->measured_time_ms > fw->delay_ms)
                        fw->erase += pr_time(
                                (fw->total_size - fw->total_written) /
                                get_avg_speed(fw));
@@ -449,8 +474,6 @@
        }
 
        start_measurement(fw);
-       if (slow_down)
-               assert(!usleep((fw->delay_ms - delay) * 1000));
        return 0;
 }
 
@@ -468,6 +491,21 @@
        return 0;
 }
 
+/* XXX Avoid duplicate this function, which was copied from libdevs.c. */
+static int write_all(int fd, const char *buf, size_t count)
+{
+       size_t done = 0;
+       do {
+               ssize_t rc = write(fd, buf + done, count - done);
+               if (rc < 0) {
+                       /* The write() failed. */
+                       return errno;
+               }
+               done += rc;
+       } while (done < count);
+       return 0;
+}
+
 #define MAX_WRITE_SIZE (1<<21) /* 2MB */
 
 /* Return true when disk is full. */
@@ -506,7 +544,6 @@
        remaining = size;
        start_measurement(fw);
        while (remaining > 0) {
-               ssize_t written;
                ssize_t write_size = fw->block_size *
                        (fw->blocks_per_delay - fw->written_blocks);
                assert(write_size > 0);
@@ -515,23 +552,11 @@
                if ((size_t)write_size > remaining)
                        write_size = remaining;
                offset = fill_buffer(buf, write_size, offset);
-               written = write(fd, buf, write_size);
-               if (written < 0) {
-                       saved_errno = errno;
-                       break;
-               }
-               if (written < write_size) {
-                       /* It must have filled up the file system.
-                        * errno should be equal to ENOSPC.
-                        */
-                       assert(write(fd, buf + written, write_size - written)
-                               < 0);
-                       saved_errno = errno;
+               saved_errno = write_all(fd, buf, write_size);
+               if (saved_errno)
                        break;
-               }
-               assert(written == write_size);
-               remaining -= written;
-               if (measure(fd, fw, written) < 0) {
+               remaining -= write_size;
+               if (measure(fd, fw, write_size) < 0) {
                        saved_errno = errno;
                        break;
                }
@@ -575,6 +600,12 @@
        printf("Free space: %.2f %s\n", f, unit);
 }
 
+static inline void pr_avg_speed(double speed)
+{
+       const char *unit = adjust_unit(&speed);
+       printf("Average writing speed: %.2f %s/s\n", speed, unit);
+}
+
 static int fill_fs(const char *path, long start_at, long end_at,
        long max_write_rate, int progress)
 {
@@ -582,6 +613,7 @@
        struct flow fw;
        long i;
        int has_suggested_max_write_rate = max_write_rate > 0;
+       struct timeval t1, t2;
 
        free_space = get_freespace(path);
        pr_freespace(free_space);
@@ -609,20 +641,30 @@
        }
 
        init_flow(&fw, free_space, max_write_rate, progress);
+       assert(!gettimeofday(&t1, NULL));
        for (i = start_at; i <= end_at; i++)
                if (create_and_fill_file(path, i, GIGABYTES,
                        &has_suggested_max_write_rate, &fw))
                        break;
+       assert(!gettimeofday(&t2, NULL));
 
        /* Final report. */
        pr_freespace(get_freespace(path));
        /* Writing speed. */
-       if (fw.measurements > 0) {
-               double speed = get_avg_speed(&fw);
-               const char *unit = adjust_unit(&speed);
-               printf("Average writing speed: %.2f %s/s\n", speed, unit);
-       } else
-               printf("Writing speed not available\n");
+       if (fw.measured_time_ms > fw.delay_ms) {
+               pr_avg_speed(get_avg_speed(&fw));
+       } else {
+               /* If the drive is too fast for the measuments above,
+                * try a coarse approximation of the writing speed.
+                */
+               int64_t total_time_ms = delay_ms(&t1, &t2);
+               if (total_time_ms > 0) {
+                       pr_avg_speed(get_avg_speed_given_time(&fw,
+                               total_time_ms));
+               } else {
+                       printf("Writing speed not available\n");
+               }
+       }
 
        return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/libdevs.c new/f3-7.2/libdevs.c
--- old/f3-7.1/libdevs.c        2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/libdevs.c        2019-06-19 20:43:19.000000000 +0200
@@ -23,7 +23,7 @@
 #include "libutils.h"
 #include "libdevs.h"
 
-static const char const *ftype_to_name[FKTY_MAX] = {
+static const char * const ftype_to_name[FKTY_MAX] = {
        [FKTY_GOOD]             = "good",
        [FKTY_BAD]              = "bad",
        [FKTY_LIMBO]            = "limbo",
@@ -413,6 +413,8 @@
        do {
                ssize_t rc = read(fd, buf + done, count - done);
                if (rc < 0) {
+                       if (errno == EINTR)
+                               continue;
                        assert(errno == EIO);
                        return - errno;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/utils.h new/f3-7.2/utils.h
--- old/f3-7.1/utils.h  2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/utils.h  2019-06-19 20:43:19.000000000 +0200
@@ -17,10 +17,11 @@
 /* Caller must free(3) the returned pointer. */
 char *full_fn_from_number(const char **filename, const char *path, long num);
 
-static inline long delay_ms(const struct timeval *t1, const struct timeval *t2)
+static inline int64_t delay_ms(const struct timeval *t1,
+       const struct timeval *t2)
 {
-       return  (t2->tv_sec  - t1->tv_sec)  * 1000 +
-               (t2->tv_usec - t1->tv_usec) / 1000;
+       return (int64_t)(t2->tv_sec  - t1->tv_sec)  * 1000 +
+                       (t2->tv_usec - t1->tv_usec) / 1000;
 }
 
 const long *ls_my_files(const char *path, long start_at, long end_at);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.1/version.h new/f3-7.2/version.h
--- old/f3-7.1/version.h        2018-07-27 10:10:35.000000000 +0200
+++ new/f3-7.2/version.h        2019-06-19 20:43:19.000000000 +0200
@@ -1,6 +1,6 @@
 #ifndef HEADER_VERSION_H
 #define HEADER_VERSION_H
 
-#define F3_STR_VERSION "7.1"
+#define F3_STR_VERSION "7.2"
 
 #endif /* HEADER_VERSION_H */


Reply via email to