Hello community,

here is the log from the commit of package f3 for openSUSE:Leap:15.2 checked in 
at 2020-05-24 18:08:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:15.2/f3 (Old)
 and      /work/SRC/openSUSE:Leap:15.2/.f3.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "f3"

Sun May 24 18:08:32 2020 rev:14 rq:807718 version:7.2

Changes:
--------
--- /work/SRC/openSUSE:Leap:15.2/f3/f3.changes  2020-01-15 14:54:31.513558945 
+0100
+++ /work/SRC/openSUSE:Leap:15.2/.f3.new.2738/f3.changes        2020-05-24 
18:08:33.266091611 +0200
@@ -1,0 +2,24 @@
+Wed May 20 11:50:43 UTC 2020 - Olav Reinert <seroto...@gmail.com>
+
+- 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)
+
+-------------------------------------------------------------------
+Mon Feb  3 12:59:26 UTC 2020 - Dominique Leuenberger <dims...@opensuse.org>
+
+- BuildRequire pkgconfig(libudev) instead of libudev-devel: allow
+  OBS to shortcut through the -mini flavors.
+
+-------------------------------------------------------------------
+Thu Jan 17 14:44:25 UTC 2019 - t.gru...@katodev.de
+
+- update to 7.1:
+    * fix compilation issues on non-Linux OSs
+    * f3write: make parameter --max-write-rate work precisely
+    * f3probe: change default reset type to RT_NONE
+- remove remove-ownership-setting.patch (accepted upstream, pull request #75) 
+
+-------------------------------------------------------------------

Old:
----
  f3-7.0.tar.gz
  remove-ownership-setting.patch

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

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

Other differences:
------------------
++++++ f3.spec ++++++
--- /var/tmp/diff_new_pack.xTpkwZ/_old  2020-05-24 18:08:33.986093169 +0200
+++ /var/tmp/diff_new_pack.xTpkwZ/_new  2020-05-24 18:08:33.986093169 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package f3
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,21 +12,21 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           f3
-Version:        7.0
+Version:        7.2
 Release:        0
 Summary:        Fight Flash Fraud / Fight Fake Flash
-License:        GPL-3.0
+License:        GPL-3.0-only
 Group:          Hardware/Other
-Url:            http://oss.digirati.com.br/f3/
+URL:            http://oss.digirati.com.br/f3/
 Source:         
https://github.com/AltraMayor/f3/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
-Patch0:         remove-ownership-setting.patch
-BuildRequires:  libudev-devel
-BuildRequires:  parted-devel
+BuildRequires:  pkgconfig
+BuildRequires:  pkgconfig(libparted)
+BuildRequires:  pkgconfig(libudev)
 
 %description
 This package contains tools for identifying fake flash drives (primarily USB
@@ -42,7 +42,6 @@
 
 %prep
 %setup -q
-%patch0
 
 %build
 # workaround for libargp problem. see:
@@ -52,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
@@ -60,16 +59,16 @@
 
 %install
 %make_install PREFIX=%{_prefix} install-extra
-# 
 
 %files
-%doc changelog README.rst LICENSE examples
+%doc changelog README.rst examples
+%license LICENSE
 %{_bindir}/f3read
 %{_bindir}/f3write
-%{_sbindir}/f3probe
-%{_sbindir}/f3brew
-%{_sbindir}/f3fix
-%{_mandir}/man1/f3read.1%{ext_man}
-%{_mandir}/man1/f3write.1%{ext_man}
+%{_bindir}/f3probe
+%{_bindir}/f3brew
+%{_bindir}/f3fix
+%{_mandir}/man1/f3read.1%{?ext_man}
+%{_mandir}/man1/f3write.1%{?ext_man}
 
 %changelog

++++++ f3-7.0.tar.gz -> f3-7.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.0/Makefile new/f3-7.2/Makefile
--- old/f3-7.0/Makefile 2017-12-21 20:32:02.000000000 +0100
+++ new/f3-7.2/Makefile 2019-06-19 20:43:19.000000000 +0200
@@ -8,19 +8,28 @@
 INSTALL = install
 LN = ln
 
+ifndef OS
+       OS = $(shell uname -s)
+endif
+ifneq ($(OS), Linux)
+       ARGP = /usr/local
+       CFLAGS += -I$(ARGP)/include
+       LDFLAGS += -L$(ARGP)/lib -largp
+endif
+
 all: $(TARGETS)
 extra: $(EXTRA_TARGETS)
 
 install: all
        $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin
-       $(INSTALL) -oroot -groot -m755 $(TARGETS) $(DESTDIR)$(PREFIX)/bin
+       $(INSTALL) -m755 $(TARGETS) $(DESTDIR)$(PREFIX)/bin
        $(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man1
-       $(INSTALL) -oroot -groot -m644 f3read.1 
$(DESTDIR)$(PREFIX)/share/man/man1
+       $(INSTALL) -m644 f3read.1 $(DESTDIR)$(PREFIX)/share/man/man1
        $(LN) -sf f3read.1 $(DESTDIR)$(PREFIX)/share/man/man1/f3write.1
 
 install-extra: extra
        $(INSTALL) -d $(DESTDIR)$(PREFIX)/bin
-       $(INSTALL) -oroot -groot -m755 $(EXTRA_TARGETS) $(DESTDIR)$(PREFIX)/bin
+       $(INSTALL) -m755 $(EXTRA_TARGETS) $(DESTDIR)$(PREFIX)/bin
 
 f3write: utils.o f3write.o
        $(CC) -o $@ $^ $(LDFLAGS) -lm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.0/README.rst new/f3-7.2/README.rst
--- old/f3-7.0/README.rst       2017-12-21 20:32:02.000000000 +0100
+++ 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.0.zip
+    $ unzip f3-7.2.zip
 
 
 Compile stable software on Linux or FreeBSD
@@ -80,7 +80,13 @@
 Compile stable software on Windows/Cygwin
 -----------------------------------------
 
-On Cygwin, you need special flags::
+If you haven't already, install the following Cygwin packages and their 
dependencies:
+
+- `gcc-core`
+- `make`
+- `libargp-devel`
+
+To build, you need special flags::
 
     export LDFLAGS="$LDFLAGS -Wl,--stack,4000000 -largp"
     make
@@ -107,8 +113,8 @@
 
     port install f3
 
-Compiling the lastest development version from the source code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Compiling the latest development version from the source code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Most of the f3 source code builds fine using XCode, the only dependency
 missing is the GNU C library "argp". You can build argp from scratch, or
@@ -129,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
 
@@ -148,22 +154,16 @@
    See https://trac.macports.org/browser/trunk/dports/sysutils/f3/Portfile
    for more information.
 
-4) Set compilation flags. These following environment variables are used
-   in the Makefile to locate the argp library:
-
-   HomeBrew::
+4) Build F3::
 
-     export CFLAGS="$CFLAGS -I/usr/local/include/"
-     export LDFLAGS="$LDFLAGS -L/usr/local/lib/ -largp"
+   When using Homebrew, you can just run::
 
-   MacPorts::
-
-     export CFLAGS="$CFLAGS -I/opt/local/include/"
-     export LDFLAGS="$LDFLAGS -L/opt/local/lib/ -largp"
+       make
 
-5) Build F3::
+   When using MacPorts, you will need to pass the location where MacPorts
+   installed argp-standalone::
 
-       make
+       make ARGP=/opt/local
 
 The extra applications for Linux
 --------------------------------
@@ -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.0/changelog new/f3-7.2/changelog
--- old/f3-7.0/changelog        2017-12-21 20:32:02.000000000 +0100
+++ new/f3-7.2/changelog        2019-06-19 20:43:19.000000000 +0200
@@ -1,3 +1,16 @@
+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
+    * f3write: make parameter --max-write-rate work precisely
+    * f3probe: change default reset type to RT_NONE
+
 Version 7.0 - Dec 21, 2017
 
     * stable version of f3probe, f3fix, and f3brew (Linux only)
@@ -52,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.0/doc/conf.py new/f3-7.2/doc/conf.py
--- old/f3-7.0/doc/conf.py      2017-12-21 20:32:02.000000000 +0100
+++ 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.0'
+version = '7.2'
 # The full version, including alpha/beta/rc tags.
-release = '7.0'
+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.0/doc/contribute.rst 
new/f3-7.2/doc/contribute.rst
--- old/f3-7.0/doc/contribute.rst       2017-12-21 20:32:02.000000000 +0100
+++ 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.0/doc/history.rst new/f3-7.2/doc/history.rst
--- old/f3-7.0/doc/history.rst  2017-12-21 20:32:02.000000000 +0100
+++ 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.0/doc/usage.rst new/f3-7.2/doc/usage.rst
--- old/f3-7.0/doc/usage.rst    2017-12-21 20:32:02.000000000 +0100
+++ 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.0
+    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.0
+    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.0
+    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.0/f3brew.c new/f3-7.2/f3brew.c
--- old/f3-7.0/f3brew.c 2017-12-21 20:32:02.000000000 +0100
+++ 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.0/f3probe.c new/f3-7.2/f3probe.c
--- old/f3-7.0/f3probe.c        2017-12-21 20:32:02.000000000 +0100
+++ 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)
@@ -520,7 +520,24 @@
                .keep_file      = false,
                .save           = true,
                .min_mem        = false,
-               .reset_type     = RT_USB,
+
+               /* RT_NONE is the only reliable reset type against fake flash.
+                * See issue #81 for details:
+                * https://github.com/AltraMayor/f3/issues/81
+                *
+                * A side benefit of this reset type is that it works on
+                * non-USB-backed drives, such as card readers that are
+                * commonly built in laptops.
+                * See issue #79 for details:
+                * https://github.com/AltraMayor/f3/issues/79
+                *
+                * A negative side effect is that f3probe runs slower
+                * for cases in which RT_USB would work. But users can
+                * still request the reset type RT_USB by
+                * passing --reset-type=1
+                */
+               .reset_type     = RT_NONE,
+
                .time_ops       = false,
                .real_size_byte = 1ULL << 31,
                .fake_size_byte = 1ULL << 34,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/f3-7.0/f3read.1 new/f3-7.2/f3read.1
--- old/f3-7.0/f3read.1 2017-12-21 20:32:02.000000000 +0100
+++ 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"  "December 2017" "F3 7.0" "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.0/f3write.c new/f3-7.2/f3write.c
--- old/f3-7.0/f3write.c        2017-12-21 20:32:02.000000000 +0100
+++ new/f3-7.2/f3write.c        2019-06-19 20:43:19.000000000 +0200
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <limits.h>
+#include <float.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/statvfs.h>
@@ -142,22 +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;
-       /* Maximum number of blocks to write before measurement.
-        * This parameter is used to bound the write rate.
-        */
-       int             max_blocks_per_delay;
-       /* Delay in miliseconds. */
-       int             delay_ms;
-       /* Number of measurements after reaching FW_STEADY state. */
-       uint64_t        measurements;
+       int64_t         blocks_per_delay;
+       /* Maximum write rate in bytes per second. */
+       double          max_write_rate;
        /* 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. */
@@ -168,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)
@@ -190,26 +189,17 @@
        fw->total_size          = total_size;
        fw->total_written       = 0;
        fw->progress            = progress;
-       fw->block_size          = 1024; /* 1KB          */
-       fw->blocks_per_delay    = 1;    /* 1KB/s        */
+       fw->block_size          = 512;  /* Bytes        */
+       fw->blocks_per_delay    = 1;    /* 512B/s       */
        fw->delay_ms            = 1000; /* 1s           */
-       fw->measurements        = 0;
+       fw->max_write_rate      = max_write_rate <= 0
+               ? DBL_MAX : max_write_rate * 1024.;
        fw->measured_blocks     = 0;
+       fw->measured_time_ms    = 0;
        fw->erase               = 0;
        assert(fw->block_size > 0);
        assert(fw->block_size % SECTOR_SIZE == 0);
 
-       /* Derive @fw->max_blocks_per_delay from @max_write_rate. */
-       if (max_write_rate <= 0) {
-               /* This is the most common case. */
-               fw->max_blocks_per_delay = INT_MAX;
-       } else {
-               fw->max_blocks_per_delay =
-                       /* Units: KB/s * ms / B/block = block */
-                       round((double)max_write_rate * fw->delay_ms
-                               / fw->block_size);
-       }
-
        move_to_inc_at_start(fw);
 }
 
@@ -236,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)
@@ -280,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);
@@ -320,8 +309,6 @@
 static inline void inc_step(struct flow *fw)
 {
        fw->blocks_per_delay += fw->step;
-       if (fw->blocks_per_delay > fw->max_blocks_per_delay)
-               fw->blocks_per_delay = fw->max_blocks_per_delay;
        fw->step *= 2;
 }
 
@@ -338,11 +325,26 @@
        dec_step(fw);
 }
 
+static inline int is_rate_above(const struct flow *fw,
+       long delay, double inst_speed)
+{
+       /* We use logical or here to enforce the lowest limit. */
+       return delay > fw->delay_ms || inst_speed > fw->max_write_rate;
+}
+
+static inline int is_rate_below(const struct flow *fw,
+       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;
+}
+
 static int measure(int fd, struct flow *fw, ssize_t written)
 {
-       long delay;
-       div_t result = div(written, fw->block_size);
-       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;
@@ -354,28 +356,63 @@
        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. */
+       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:
-               if (delay > fw->delay_ms) {
+               if (is_rate_above(fw, delay, inst_speed)) {
                        move_to_search(fw,
                                fw->blocks_per_delay - fw->step / 2,
                                fw->blocks_per_delay);
-               } else if (delay < fw->delay_ms
-                       && fw->blocks_per_delay < fw->max_blocks_per_delay) {
+               } else if (is_rate_below(fw, delay, inst_speed)) {
                        inc_step(fw);
                } else
                        move_to_steady(fw);
                break;
 
        case FW_DEC:
-               if (delay > fw->delay_ms) {
+               if (is_rate_above(fw, delay, inst_speed)) {
                        dec_step(fw);
-               } else if (delay < fw->delay_ms) {
+               } else if (is_rate_below(fw, delay, inst_speed)) {
                        move_to_search(fw, fw->blocks_per_delay,
                                fw->blocks_per_delay + fw->step / 2);
                } else
@@ -388,42 +425,34 @@
                        break;
                }
 
-               if (delay > fw->delay_ms) {
+               if (is_rate_above(fw, delay, inst_speed)) {
                        fw->bpd2 = fw->blocks_per_delay;
                        fw->blocks_per_delay = (fw->bpd1 + fw->bpd2) / 2;
-               } else if (delay < fw->delay_ms) {
+               } else if (is_rate_below(fw, delay, inst_speed)) {
                        fw->bpd1 = fw->blocks_per_delay;
                        fw->blocks_per_delay = (fw->bpd1 + fw->bpd2) / 2;
                } else
                        move_to_steady(fw);
                break;
 
-       case FW_STEADY:
-               update_mean(fw);
-
+       case FW_STEADY: {
                if (delay <= fw->delay_ms) {
-                       if (fw->blocks_per_delay < fw->max_blocks_per_delay) {
+                       if (inst_speed < fw->max_write_rate) {
                                move_to_inc(fw);
-                       } else {
-                               /* Since we are already writing at
-                                * maximum allowed rate, wait until next cycle.
-                                */
-                               slow_down = true;
+                       } else if (inst_speed > fw->max_write_rate) {
+                               move_to_dec(fw);
                        }
                } else if (fw->blocks_per_delay > 1) {
                        move_to_dec(fw);
                }
                break;
+       }
 
        default:
                assert(0);
        }
 
        if (fw->progress) {
-               /* Instantaneous speed. */
-               double inst_speed =
-                       (double)fw->blocks_per_delay * fw->block_size * 1000 /
-                       fw->delay_ms;
                const char *unit = adjust_unit(&inst_speed);
                double percent;
                /* The following shouldn't be necessary, but sometimes
@@ -437,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));
@@ -445,8 +474,6 @@
        }
 
        start_measurement(fw);
-       if (slow_down)
-               assert(!usleep((fw->delay_ms - delay) * 1000));
        return 0;
 }
 
@@ -464,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. */
@@ -502,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);
@@ -511,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;
+               saved_errno = write_all(fd, buf, write_size);
+               if (saved_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;
-                       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;
                }
@@ -571,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)
 {
@@ -578,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);
@@ -605,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.0/libdevs.c new/f3-7.2/libdevs.c
--- old/f3-7.0/libdevs.c        2017-12-21 20:32:02.000000000 +0100
+++ 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.0/utils.h new/f3-7.2/utils.h
--- old/f3-7.0/utils.h  2017-12-21 20:32:02.000000000 +0100
+++ 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.0/version.h new/f3-7.2/version.h
--- old/f3-7.0/version.h        2017-12-21 20:32:02.000000000 +0100
+++ 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.0"
+#define F3_STR_VERSION "7.2"
 
 #endif /* HEADER_VERSION_H */


Reply via email to