KDE Says It Fixed a 15-Year-Old Copy Bug That Made Progress Bars Lie
For a decade and a half, Dolphin told you a copy was done while the data was just sitting in RAM. The new fix shipping with KDE Frameworks 6.32 changes that.
Almost nobody thinks about the fraction of a second after a copy dialog declares victory. In most desktops that moment is honest: the bar hits the end and the data really is there. KDE's file manager and the I/O framework underneath it, KIO, stopped keeping that promise around 2011, and only now has someone fixed it.
KDE developer Méven Car posted a fairly exhaustive write-up of the fix. He called it the worst KIO bug he had ever chased and spent a paragraph calling it a white whale. The code is merged. It ships with KDE Frameworks 6.32, which is slated for November 13.
The problem and its fifteen-year history
Drag a big folder onto a USB stick, watch the bar race to done in what looks like an instant, and yank the drive out. On a fast SSD you'd never notice, since the kernel flushes its cache almost at once. On something slow, like a cheap USB 2.0 stick writing a few megabytes a second, the dialog declared victory while the data still sat in memory. Pull the stick and the files simply were gone.
There was a second wrinkle, and it was actively insulting. Early reports noted Dolphin showing speeds of roughly 50 MB/s to a device physically capped at 12 Mbit/s. That's a gap of roughly 300 times. As one kernel developer put it, the code reports a copy finished when it hadn't even started.
To see what actually breaks, you have to watch where the bytes go. When an app copies a file it hands the data to the kernel's write call, which returns the moment the data reaches the page cache, the kernel's memory buffer. The kernel then flushes those pages to the real device later, on its own schedule. A local SSD means microseconds. A slow or networked destination can mean minutes.
KIO's copy worker treats the return of write as progress. So the bar tracks how fast KIO filled memory, not how fast data reached the device.
Removable storage hits first. The bar races ahead, reports done early, and yanking the drive mid-flush loses data quietly.
Then come network filesystems. NFS, SMB, Ceph, GlusterFS, 9p, sshfs, FUSE. A big copy leaves hundreds of megabytes queued for the server. On SMB with the default cache settings, reading a file waits until its dirty data is flushed. Folder listings read files, so over a slow link almost every attempt to browse the destination during a copy blocked for 15 to 20 seconds. The share just froze.
A move is worse still, which is what made this urgent. KIO deletes the source files right after each copy completes, even when those copies might still be living in memory.
The bug's paper trail runs back to September 3, 2011. It was filed as bug 281270 against KDE 4.7 by a user named Alexander on Arch Linux, titled something close to "the speed and progress reflect copying to the local cache rather than the disk." Two days later, KDE maintainer Christoph Feck asked whether there was a way to know when data was really on disk without massive slowdowns. Two weeks after that the reporter relayed kernel USB developer Alan Stern's suggestion of sync_file_range(). Feck said it looked like exactly what they needed. That's the call KIO now uses.
Nothing moved for years. Comments climbed to 77, 17 duplicates piled up, and the tracker stayed stubbornly open. In 2021 Nate Graham bumped it to highest priority because of the move hazard. Feck tested Linux 6.5's cachestat call in 2024, but that only works one file at a time.
Car, who's worked on KIO since 2018, tried twice in 2024 to get sync_file_range right. Both failed. One merge request left the path commented out. The other had the worker wait on a chunk it had just handed over, which hadn't even started writing, so it never actually waited. The trick, it turns out, is waiting for the window before the one you just passed off.
How the fix works, and what it costs
The core idea is an adaptive writeback window. Waiting for the device after every write is correct but glacial; waiting only at the end keeps the whole bar lying. KIO threads a needle in between.
Data copies in windows worth about 200 ms of writeback. Each starts at 1 MiB, can double at most per window, and caps at 16 MiB, or 128 MiB on CIFS. When a window fills, a helper thread writes it back and waits while the next one starts filling. The copy only blocks when the window before the one just handed off hasn't been written yet. So at most two windows of data sit in memory without being on the device, and the bar is never more than one window ahead of reality.
The helper thread exists for one specific reason: CIFS. The kernel client for Samba shares does a lot of work to start a window's writeback, sending data and waiting for transfer credits, blocking for roughly 157 ms per 128 MiB window. Without a separate thread KIO couldn't fill the next window while sending the previous one. Now they overlap.
The end of a copy still needs a real flush, and small files are the annoying part. An fsync per file made 3,000 files of 16 KiB take 10 seconds instead of 0.04 s on a local disk. So the worker flushes nothing on its own. Instead it notifies the job, which sends one extra command before reporting success: write back the whole filesystem with a single syncfs. The notification just says "Writing the copied data to the device..." If that flush fails, the whole copy fails, because the data may not be on the device at all.
Moves now keep their source files until the flush succeeds, deleting them only after. A source that changed while waiting stays put with a warning.
Removable detection is its own little puzzle. A filesystem type doesn't tell you whether a device can be unplugged: exFAT can be a memory card, FAT is also an EFI partition, and most USB disks don't even report removable media. KIO reads the answer from sysfs and the mount table instead, with two earlier changes speeding it up. One caches mounts by the id statx returns. Another uses statmount so an unresponsive server no longer blocks the lookup, dropping it from over 15 seconds to about a millisecond.
Same release carries a bonus speedup. Copying between two filesystems previously fell back to slow per-buffer reads and writes after Linux broke the fast path. MR 2520 restores an in-kernel sendfile fallback, turning a 1 GiB tmpfs to ext4 copy from 443 ms down to 272 ms.
Car's own numbers back it up, and they're worth a look. He ran KIO's copy job before and after, with another thread listing the destination every 50 ms.
On a USB 2.0 stick writing about 2.3 MB/s, a 128 MiB file showed complete in 0.06 to 0.13 seconds before the fix, and 28.1 seconds after. Data actually hit the stick in 68 to 91 seconds before, and 28.1 seconds after. Progress was 128 MiB ahead of the stick before. Now it's 3 MiB.
The 3,000 small files tell the same story. Completion landed at 1.2 seconds before, while data arrived 185.2 seconds later, versus 183.9 seconds on both counts after. They finally match.
Over a slow SMB link at roughly 5 MB/s, the slowest folder listing during a 256 MiB copy dropped from 27.4 and 15.3 seconds to 1.70 seconds, with throughput basically unchanged. A 4 GiB NFS copy cut its median listing from 24 ms to 11 ms.
Car is honest that the window costs a few percent on fast links, and that the USB "speedup" is just the clock now including real write time rather than any genuine gain. Fair enough.
Slow mounts have a habit of freezing Dolphin, captured under bug 423187. Frank Gehann, in one memorable comment, copied a 100 MB file to an SMB share while browsing it and found two culprits. Dolphin's main thread was waiting on the share, and folder listings queued behind the upload. The writeback window handles the second. A statmount change handles part of the first.
Car also recounts a rabbit hole. During large USB copies, listing a folder on the stick sometimes took 15 seconds. The culprit turned out to be the stick itself, not KIO. Roughly every 8 seconds a single 120 KiB write took 4 to 7 seconds, and listings waited behind a page stuck in that write. KIO can't fix a device that stalls for seconds. The real win was confirming the copy wasn't to blame.
One caveat worth holding onto: this only touches removable and network destinations. Local fixed disks keep their exact current behavior, so if you mostly copy between SSDs nothing changes for you.
It's arguably one of the more unglamorous wins in recent KDE history. No new feature, no fanfare, just a progress bar that finally means something. But the machinery underneath is real, threading sync_file_range through an adaptive window, a helper thread, and two new lookup calls to keep a copy fast while keeping it honest. KIO is reportedly one of the only file managers using sync_file_range this way, which says something about how deep this went.
KDE Frameworks 6.32 is expected to be tagged November 6 and released November 13. All of Car's changes are merged and will ride along. The previous release, 6.30.0, shipped September 9 and already contains the mount-caching work.
This is one of several related fixes in Car's recent output, following posts on copying many small files fast and on the Dolphin 26.08 performance work.
