]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: ignore 33553920 byte optimal I/O size
authorRyan Finnie <ryan@finnie.org>
Sun, 27 Dec 2020 18:01:26 +0000 (10:01 -0800)
committerKarel Zak <kzak@redhat.com>
Wed, 10 Feb 2021 09:00:00 +0000 (10:00 +0100)
33553920 byte optimal I/O size arises from badly-implemented USB SATA
adapters reporting 0xffff 512 byte sectors (32 MiB - 512).  Commit
acb7651f8897ae73d0f45dd75bc87630001c61b9 indirectly addresses this by
ignoring the optimal I/O size if it's not a multiple of the physical
sector size.  That works if the physical sector size is 4096, but
33553920 optimal is allowed for 512 physical.

This commit explicitly ignores 33553920, as there is no legitimate
situation where this number would be the real optimal I/O size.

Signed-off-by: Ryan Finnie <ryan@finnie.org>
Closes: https://github.com/karelzak/util-linux/issues/1221
libfdisk/src/alignment.c

index 3d02546341145b6ec2d04f67a2b14cff860ea36d..3ae7219132e0b8f3c8a99a418b37ccc5f756c1e1 100644 (file)
@@ -541,12 +541,16 @@ int fdisk_discover_topology(struct fdisk_context *cxt)
                                /* optimal I/O is optional, default to minimum IO */
                                cxt->io_size = cxt->min_io_size;
 
-                       /* ignore optimal I/O if not aligned to phy.sector size */
-                       if (cxt->io_size
-                           && cxt->phy_sector_size
-                           && (cxt->io_size % cxt->phy_sector_size) != 0) {
-                               DBG(CXT, ul_debugobj(cxt, "ignore misaligned I/O size"));
-                               cxt->io_size = cxt->phy_sector_size;
+                       if (cxt->io_size && cxt->phy_sector_size) {
+                               if (cxt->io_size == 33553920) {
+                                       /* 33553920 (32 MiB - 512) is always a controller error */
+                                       DBG(CXT, ul_debugobj(cxt, "ignore bad I/O size 33553920"));
+                                       cxt->io_size = cxt->phy_sector_size;
+                               } else if ((cxt->io_size % cxt->phy_sector_size) != 0) {
+                                       /* ignore optimal I/O if not aligned to phy.sector size */
+                                       DBG(CXT, ul_debugobj(cxt, "ignore misaligned I/O size"));
+                                       cxt->io_size = cxt->phy_sector_size;
+                               }
                        }
 
                }