Skip to content

KFileItem: Determine mime type only from extension for slow items (remote FS)

Sergey Katunin requested to merge sgakerru/kio:slow-items-mimetype-fix into master

The problem is relevant only for locally mounted remote FS, and in fact does not make sense without this MR: kcoreaddons!421 (merged)

I have encountered interface freezes and slow operation of a folder in Dolphin mounted via davfs2 as described here: https://bugs.kde.org/show_bug.cgi?id=372849.

However, the problem was not only with loading thumbnails, as it was supposed to be, even when I turned them off, I ran into the same problem. Davfs2 downloaded files on Dolphin's demand (since there is no such problem via mc). As I found out, this is due to the fact that starting with the change system/dolphin@7f3967cf

    if (m_requestRole[IsHiddenRole]) {
        data.insert(sharedValue("isHidden"), item.isHidden() || item.mimetype() == QStringLiteral("application/x-trash"));
    }

Dolphin tries to find out the mime type of the file in KFileItemModel::retrieveData. Which in turn causes the KFileItemPrivate::determineMimeTypeHelper method to define mime type via the Qt method QMimeDatabase::mimeTypeForUrl without explicitly specifying that type definitions by extension are required (MatchExtension mode). On Qt5 (relevant, apparently, up to Qt 6.3.0), in the case of the MatchDefault mode, file.open is called even before the algorithm determines whether to return mime type based on content or extension. Calling file.open in the case of the davfs2 driver causes files to be uploaded to execute this open system call.

Since Qt 6.3.0, this place has been optimized (https://github.com/qt/qtbase/commit/d797e3c88ed7be6e2b683984950334a8054728a9): file.open will be called later, exactly in the case when the algorithm decides to determine the mime type by content (for example, if it was not possible to determine the mime type by extension), but this only partially solves the problem (there will still be cases, but more rare than now, when file.open will be called for a remote file).

Actually, for protocols like webdav:// from kio-fuse, this problem is not affected, since at the level of the QMimeDatabase::mimeTypeForUrl method it is clearly visible that the file url is non-local and therefore the type definition is only due to the extension.

My suggestion is that for slow items (isSlow() == true) explicitly define the type by extension.

P.S In general, the problem with the Dolphin interface hanging when using davfs2 seems to be mostly related to davfs2 itself. It's easy to see if you run Dolphin and mc at the same time, and when Dolphin starts downloading files to read mime type or thumbnails, then everything freezes in mc and nothing will work. As I understand it, while the file is downloading in davfs2, it blocks the work of the process that accesses the WebDAV folder (does not allow you to download another file, does not allow you to download information about the directory).

On rclone and the remote folder in Dolphin (webdav://, I assume this is kio-fuse) - this problem does not occur, since to determine the type - kio-fuse does not do file.open, and rclone apparently has some kind of optimization and does not download a file when calling this system function file.open, waiting for the read call directly, and for thumbnails in both the case of kio-fuse and in the case of rclone - files are uploaded asynchronously in the background, without blocking the explorer interface.

Thus, this optimization should primarily help with bad remote FS drivers, which, when calling open or read, attempt to pre-download the file to the cache. As they say, better safe than sorry.

P.P.S Since mc does not define either mime type in this way, does not download thumbnails, it does not slow down even with davfs2 when navigating through such directories. I also checked for nautilus, it is partially affected by the problem (apparently because of the thumbnails), but does not define the mime type for all files in the folder, and therefore worked many times faster than Dolphin with davfs2.

Edited by Sergey Katunin

Merge request reports