Commit 6e71b337 authored by Fabian Vogt's avatar Fabian Vogt

Print an error message and exit on 32bit with Linux kernel < 5.2

Might lead to false positives due to upstream and downstream backports,
but better be save than sorry.
parent 1aeefc01
......@@ -25,6 +25,11 @@
#include <QDateTime>
#include <QDebug>
#include <QVersionNumber>
#ifdef Q_OS_LINUX
#include <sys/utsname.h>
#endif
#include <KIO/ListJob>
#include <KIO/MkdirJob>
......@@ -124,7 +129,6 @@ int KIOFuseVFS::signalFd[2];
KIOFuseVFS::KIOFuseVFS(QObject *parent)
: QObject(parent)
{
static_assert(sizeof(off_t) >= 8, "Please compile with -D_FILE_OFFSET_BITS=64 to allow working with large (>4GB) files");
struct stat attr = {};
fillStatForFile(attr);
attr.st_mode = S_IFDIR | 0755;
......@@ -144,6 +148,9 @@ KIOFuseVFS::~KIOFuseVFS()
bool KIOFuseVFS::start(struct fuse_args &args, const QString& mountpoint)
{
if(!isEnvironmentValid())
return false;
stop();
m_fuseSession = fuse_session_new(&args, &fuse_ll_ops, sizeof(fuse_ll_ops), this);
......@@ -1039,6 +1046,34 @@ void KIOFuseVFS::fsync(fuse_req_t req, fuse_ino_t ino, int datasync, fuse_file_i
});
}
bool KIOFuseVFS::isEnvironmentValid()
{
static_assert(sizeof(off_t) >= 8, "Please compile with -D_FILE_OFFSET_BITS=64 to allow working with large (>4GB) files");
#ifdef Q_OS_LINUX
// On 32bit Linux before "fuse: fix writepages on 32bit", writes past 4GiB were silently discarded.
// Technically this would have to check the kernel's bitness, but that's not easily possible.
if(sizeof(size_t) != sizeof(off_t))
{
struct utsname uts;
if(uname(&uts) != 0)
return false;
auto kernelversion = QVersionNumber::fromString(QLatin1String(uts.release));
if(kernelversion < QVersionNumber(5, 2))
{
qCritical(KIOFUSE_LOG) << "You're running kio-fuse on an older 32-bit kernel, which can lead to data loss.\n"
"Please use a newer one or make sure that the 'fuse: fix writepages on 32bit' commit "
"is part of the kernel and then build kio-fuse with this check adjusted.\n"
"If you don't know how to do that, please file a bug at your distro.";
return false;
}
}
#endif
return true;
}
std::shared_ptr<KIOFuseNode> KIOFuseVFS::nodeByName(const std::shared_ptr<KIOFuseNode> &parent, const QString name) const
{
for(auto ino : std::dynamic_pointer_cast<const KIOFuseDirNode>(parent)->m_childrenInos)
......
......@@ -96,7 +96,10 @@ private:
static void flush(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
static void release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
static void fsync(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi);
/** Does some checks of the environment. Returns false if a critical issue was found. */
bool isEnvironmentValid();
/** Setups signal handlers. Returns true if successful, false otherwise **/
bool setupSignalHandlers();
/** Reverts to default signal handlers. Returns true if successful, false otherwise. **/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment