Move the file-cloning code from QFSFileEngine to QFileSystemEngine

Change-Id: I02d22222fff64d4dbda4fffd14d1c1bbf48385ff
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Thiago Macieira 2017-07-16 01:19:23 -07:00 committed by Simon Hausmann
parent 750a252b89
commit 26094982f8
3 changed files with 24 additions and 9 deletions

View File

@ -91,6 +91,7 @@ public:
static bool fillMetaData(const QFileSystemEntry &entry, QFileSystemMetaData &data,
QFileSystemMetaData::MetaDataFlags what);
#if defined(Q_OS_UNIX)
static bool cloneFile(int srcfd, int dstfd, const QFileSystemMetaData &knownData);
static bool fillMetaData(int fd, QFileSystemMetaData &data); // what = PosixStatFlags
static QByteArray id(int fd);
static bool setFileTime(int fd, const QDateTime &newDate,

View File

@ -78,9 +78,16 @@ extern "C" NSString *NSTemporaryDirectory();
#endif
#if defined(Q_OS_LINUX)
# include <sys/ioctl.h>
# include <sys/syscall.h>
# include <sys/sendfile.h>
# include <linux/fs.h>
// in case linux/fs.h is too old and doesn't define it:
#ifndef FICLONE
# define FICLONE _IOW(0x94, 9, int)
#endif
# if !QT_CONFIG(renameat2) && defined(SYS_renameat2)
static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags)
{ return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); }
@ -1065,6 +1072,19 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
return data.hasFlags(what);
}
// static
bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaData &knownData)
{
#if defined(Q_OS_LINUX)
// try FICLONE (only works on regular files and only on certain fs)
return ::ioctl(dstfd, FICLONE, srcfd) == 0;
#else
Q_UNUSED(srcfd);
Q_UNUSED(dstfd);
return false;
#endif
}
// Note: if \a shouldMkdirFirst is false, we assume the caller did try to mkdir
// before calling this function.
static bool createDirectoryWithParents(const QByteArray &nativeName, bool shouldMkdirFirst = true)

View File

@ -737,19 +737,13 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
*/
bool QFSFileEngine::cloneTo(QAbstractFileEngine *target)
{
Q_D(QFSFileEngine);
if ((target->fileFlags(LocalDiskFlag) & LocalDiskFlag) == 0)
return false;
#if defined(Q_OS_LINUX)
Q_D(QFSFileEngine);
# if !defined FICLONE
# define FICLONE _IOW (0x94, 9, int)
# endif
int srcfd = d->nativeHandle();
int dstfd = target->handle();
return ::ioctl(dstfd, FICLONE, srcfd) == 0;
#else
return false;
#endif
return QFileSystemEngine::cloneFile(srcfd, dstfd, d->metaData);
}
QT_END_NAMESPACE