From 6b1c45bc4eb70afe5dabf59db7a3e97c7d1c3aaa Mon Sep 17 00:00:00 2001 From: "liyigang1@uniontech.com" Date: Thu, 15 Oct 2026 14:38:29 +0800 Subject: [PATCH] fix(dfm-io): prevent readlink blocking on GVFS paths in resolveSymlink Add DFMUtils::isGvfsFile() guard in DLocalHelper::resolveSymlink() to stop symlink resolution when the target is a GVFS (remote) path, avoiding synchronous readlink() calls that block on network I/O. Also extend isGvfsFile() regex to match /media/ smbmounts paths in addition to /run/media/. --- src/dfm-io/dfm-io/dfmio_utils.cpp | 2 +- src/dfm-io/dfm-io/utils/dlocalhelper.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dfm-io/dfm-io/dfmio_utils.cpp b/src/dfm-io/dfm-io/dfmio_utils.cpp index 90cf7d1b..265f62db 100644 --- a/src/dfm-io/dfm-io/dfmio_utils.cpp +++ b/src/dfm-io/dfm-io/dfmio_utils.cpp @@ -350,7 +350,7 @@ bool DFMUtils::isGvfsFile(const QUrl &url) return false; const QString &path = url.toLocalFile(); - static const QString *gvfsMatch = new QString{ "(^/run/user/\\d+/gvfs/|^/root/.gvfs/|^/media/[\\s\\S]*/smbmounts)" }; + static const QString *gvfsMatch = new QString{ "(^/run/user/\\d+/gvfs/|^/root/.gvfs/|^/(?:run/)?media/[\\s\\S]*/smbmounts)" }; // TODO(xust) /media/$USER/smbmounts might be changed in the future. QRegularExpression re { *gvfsMatch }; QRegularExpressionMatch match { re.match(path) }; diff --git a/src/dfm-io/dfm-io/utils/dlocalhelper.cpp b/src/dfm-io/dfm-io/utils/dlocalhelper.cpp index 5cf0fd32..e98e6cb2 100644 --- a/src/dfm-io/dfm-io/utils/dlocalhelper.cpp +++ b/src/dfm-io/dfm-io/utils/dlocalhelper.cpp @@ -1284,14 +1284,17 @@ QString DLocalHelper::resolveSymlink(const QUrl &url) { QSet visited; QString target = DLocalHelper::symlinkTarget(url); + if (DFMUtils::isGvfsFile(QUrl::fromLocalFile(target))) + return target; // Remote target: stop resolving, further readlink/stat would block on network I/O while (!target.isEmpty()) { if (visited.contains(target)) return QString(); // Cycle detected: return empty visited.insert(target); - QUrl newUrl = QUrl::fromLocalFile(target); - QString nextTarget = DLocalHelper::symlinkTarget(newUrl); + QString nextTarget = DLocalHelper::symlinkTarget(QUrl::fromLocalFile(target)); if (nextTarget.isEmpty()) break; + if (DFMUtils::isGvfsFile(QUrl::fromLocalFile(nextTarget))) + return nextTarget; // Remote target: stop resolving, further readlink/stat would block on network I/O target = nextTarget; } return target;