SKYHOUSE.dev Journal

Maintaining the Cloud Fortress

The DAS Was Running at USB 2.0 the Whole Time

Why: Downloading anything in a browser had become unusable — 2 to 5 minutes just to get the "where do you want to save this?" dialog to appear, more multi-minute stalls while navigating it, and downloads that silently refused to complete after all that.

The symptom pointed at the browser, but the browser was innocent. The whole machine was freezing on I/O roughly 39% of every wall-clock second, and the reason was that the new DAS — the one bought specifically to fix our storage problems — had been quietly negotiating a USB 2.0 link since the day it was plugged in. We found it, fixed it, and got a 6× throughput improvement plus a bay we didn't know was missing.

1. From "slow downloads" to "the kernel is wedged"

The first useful number was pressure-stall information, which is much more diagnostic than load average:

That last pair is the tell: 99% busy at terrible throughput means the bottleneck is the transport, not the platter.

2. Root cause — a USB 2.0 link, not a USB 2.0 cable

The DAS bridge reported /sys/bus/usb/devices/1-2/speed = 480. Four drives (later five) were sharing a single 480 Mbit/s pipe. Two compounding factors made it far worse than the raw bandwidth suggests:

We assumed a bad cable. It was the wall socket. Damien swapped the DAS and one easystore between sockets, each keeping its own cable, which turned out to be a clean controlled experiment:

Same drive, same cable, 42 vs 202 MB/s depending only on which hole it sits in. That rear socket carries no SuperSpeed pairs at all.

3. Why this is easy to miss: one socket, two logical ports

Worth writing down because it cost us time. On xHCI, a physical socket wired for USB 3 enumerates as two ports — a USB 2.0 half on Bus 001 and a SuperSpeed half on Bus 002. A device that shows up on Bus 001 is therefore not necessarily in the wrong socket; it may be in a good socket whose SuperSpeed link failed to train. The way to tell them apart is whether the socket has a Bus 002 twin at all. Ours didn't — it is a USB 2.0-only socket by design, not a broken USB 3 one.

The controller exposes 7 SuperSpeed root ports, of which only 2 are in use. There is no shortage of fast ports; we were simply using a slow one.

4. Fixing the UAS guard before touching the cable

Moving to SuperSpeed was not safe to do blind. The 2026-07-06 outage was caused by UAS flooding, and the guard we added then was usb-storage.quirks=152d:0583:u on the kernel cmdline. Checking the live hardware, the bridge in this enclosure enumerates as 152d:0567 (JMS567) — so that quirk had never matched anything. It appeared to be working only because USB 2.0 never offers UAS in the first place. Going to SuperSpeed would have re-armed the exact failure mode.

After the reboot the DAS came up on the SuperSpeed port bound to usb-storage, not uas. The quirk holds.

5. What was actually consuming the bandwidth

The link was the ceiling, but something had to hit it. Per-process I/O sampling found Nautilus reading ~17 MB/s and writing ~17 MB/s continuously — generating thumbnails for a Google Takeout dump at /media/plex3/Downloads/takeout-20260720.../Google Photos/. That one background job consumed the entire USB 2.0 budget, and because all DAS bays share a single usb-storage thread, it stalled /media/plex1 too.

Killing it alone dropped full avg10 from 38.88% to 1.52% before any hardware change — which confirmed the diagnosis on the spot.

The browser connection: Chrome's default_directory was /media/plex3/Downloads — the saturated drive — and the GTK file chooser stat()s the download directory plus every bookmark before it can draw. Three bookmarks lived behind the blocked thread. Hence a five-minute dialog.

6. A fifth bay we didn't know was missing

At SuperSpeed the bridge enumerated five drives instead of four. The newcomer is a Seagate ST10000DM005-3AW101 (serial WP001CYM), which mounted itself at /media/plex3_backup — it had been sitting in /etc/fstab with nofail the entire time, failing silently. At 480 Mbit the JMS567 could not enumerate all five bays reliably. We had assumed that drive was outside the DAS; it never was.

This also means the #ABSENT-20260706 comment on the plex3_backup line in /etc/smartd.conf is now wrong and should be re-enabled (noted below as outstanding).

7. Results

This reboot also closes the validation item left open on 2026-07-06: the box was rebooted with the DAS attached and came up clean, with no POST hang and no USB crash flood. The "post-boot hotplug only" restriction on the DAS can be retired.

8. New tool: das-check.sh

Added /home/plex/das-check.sh (companion to the existing das-up.sh / das-down.sh). One command prints the active quirk string, every USB mass-storage device's negotiated link speed with a loud flag on anything that fell back to 480 Mbit, each disk's driver and max_sectors_kb, current I/O pressure, and any blocked processes. It also shouts if anything binds uas. This is the first thing to run after any DAS re-cabling or reboot.

The bcdUSB discriminator — the single most useful trick from this session. When every socket is unlabelled and identical, /sys/bus/usb/devices/<port>/version tells you what a device is capable of, independent of what it currently negotiated:

This is what separates "this device is slow" from "this device is being made slow", and it works without unplugging anything. das-check.sh now prints the version column and classifies every device on this basis. Corollary worth remembering: a USB 2.0 device can never map your sockets for you — with no SuperSpeed pins it enumerates on Bus 001 in a fast socket and a slow one alike, so probing requires a device that reports 2.10 or better and a known-good USB 3 cable. Validate the probe in a known-fast socket before trusting its verdict elsewhere.

Note: devices at 1-1.x legitimately show 480 Mbit — they sit downstream of a hub that is itself linked at 480, so they are capped regardless of their own capability. das-check.sh labels these separately rather than flagging them as faults.

9. Outstanding

The DAS was never the problem, and neither was its cable — it spent its whole life so far breathing through a USB 2.0 straw, and we found a lost 10 TB drive by widening it.

← Back to Admin Hub