From 658d873efb95e78dfcbc216e531261e84225d89f Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Tue, 14 Nov 2017 21:37:50 -0800 Subject: [PATCH] dll: fuse: streamline time calculations --- inc/winfsp/winfsp.h | 15 ++++++++++++++ src/dll/fuse/fuse.c | 10 ++++----- src/dll/fuse/fuse_intf.c | 44 ++++++++-------------------------------- 3 files changed, 27 insertions(+), 42 deletions(-) diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 7c0951be..9fd5b97f 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1472,6 +1472,21 @@ NTSTATUS FspPosixMapPosixToWindowsPath(const char *PosixPath, PWSTR *PWindowsPat FSP_API VOID FspPosixDeletePath(void *Path); FSP_API VOID FspPosixEncodeWindowsPath(PWSTR WindowsPath, ULONG Size); FSP_API VOID FspPosixDecodeWindowsPath(PWSTR WindowsPath, ULONG Size); +static inline +VOID FspPosixFileTimeToUnixTime(UINT64 FileTime0, __int3264 UnixTime[2]) +{ + INT64 FileTime = (INT64)FileTime0 - 116444736000000000LL; + UnixTime[0] = (__int3264)(FileTime / 10000000); + UnixTime[1] = (__int3264)(FileTime % 10000000 * 100); + /* may produce negative nsec for times before UNIX epoch; strictly speaking this is incorrect */ +} +static inline +VOID FspPosixUnixTimeToFileTime(const __int3264 UnixTime[2], PUINT64 PFileTime) +{ + INT64 FileTime = (INT64)UnixTime[0] * 10000000 + (INT64)UnixTime[1] / 100 + + 116444736000000000LL; + *PFileTime = FileTime; +} /* * Path Handling diff --git a/src/dll/fuse/fuse.c b/src/dll/fuse/fuse.c index 1f634111..b2ba30bd 100644 --- a/src/dll/fuse/fuse.c +++ b/src/dll/fuse/fuse.c @@ -355,14 +355,12 @@ static NTSTATUS fsp_fuse_svcstart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) if (0 == f->VolumeParams.VolumeCreationTime) { if (0 != stbuf.st_birthtim.tv_sec) - f->VolumeParams.VolumeCreationTime = - Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_birthtim.tv_nsec / 100; + FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim, + &f->VolumeParams.VolumeCreationTime); else if (0 != stbuf.st_ctim.tv_sec) - f->VolumeParams.VolumeCreationTime = - Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_ctim.tv_nsec / 100; + FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim, + &f->VolumeParams.VolumeCreationTime); } } diff --git a/src/dll/fuse/fuse_intf.c b/src/dll/fuse/fuse_intf.c index ae9fe434..7e221d9e 100644 --- a/src/dll/fuse/fuse_intf.c +++ b/src/dll/fuse/fuse_intf.c @@ -428,18 +428,10 @@ static NTSTATUS fsp_fuse_intf_GetFileInfoFunnel(FSP_FILE_SYSTEM *FileSystem, FileInfo->FileSize = stbuf.st_size; FileInfo->AllocationSize = (FileInfo->FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; - FileInfo->CreationTime = - Int32x32To64(stbuf.st_birthtim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_birthtim.tv_nsec / 100; - FileInfo->LastAccessTime = - Int32x32To64(stbuf.st_atim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_atim.tv_nsec / 100; - FileInfo->LastWriteTime = - Int32x32To64(stbuf.st_mtim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_mtim.tv_nsec / 100; - FileInfo->ChangeTime = - Int32x32To64(stbuf.st_ctim.tv_sec, 10000000) + 116444736000000000 + - stbuf.st_ctim.tv_nsec / 100; + FspPosixUnixTimeToFileTime((void *)&stbuf.st_birthtim, &FileInfo->CreationTime); + FspPosixUnixTimeToFileTime((void *)&stbuf.st_atim, &FileInfo->LastAccessTime); + FspPosixUnixTimeToFileTime((void *)&stbuf.st_mtim, &FileInfo->LastWriteTime); + FspPosixUnixTimeToFileTime((void *)&stbuf.st_ctim, &FileInfo->ChangeTime); FileInfo->IndexNumber = stbuf.st_ino; return STATUS_SUCCESS; @@ -1306,37 +1298,17 @@ static NTSTATUS fsp_fuse_intf_SetBasicInfo(FSP_FILE_SYSTEM *FileSystem, LastWriteTime = FileInfoBuf.LastWriteTime; } - /* UNIX epoch in 100-ns intervals */ - LastAccessTime -= 116444736000000000; - LastWriteTime -= 116444736000000000; - + FspPosixFileTimeToUnixTime(LastAccessTime, (void *)&tv[0]); + FspPosixFileTimeToUnixTime(LastWriteTime, (void *)&tv[1]); if (0 != f->ops.utimens) { -#if defined(_WIN64) - tv[0].tv_sec = (int64_t)(LastAccessTime / 10000000); - tv[0].tv_nsec = (int64_t)(LastAccessTime % 10000000) * 100; - tv[1].tv_sec = (int64_t)(LastWriteTime / 10000000); - tv[1].tv_nsec = (int64_t)(LastWriteTime % 10000000) * 100; -#else - tv[0].tv_sec = (int32_t)(LastAccessTime / 10000000); - tv[0].tv_nsec = (int32_t)(LastAccessTime % 10000000) * 100; - tv[1].tv_sec = (int32_t)(LastWriteTime / 10000000); - tv[1].tv_nsec = (int32_t)(LastWriteTime % 10000000) * 100; -#endif - err = f->ops.utimens(filedesc->PosixPath, tv); Result = fsp_fuse_ntstatus_from_errno(f->env, err); } else { -#if defined(_WIN64) - timbuf.actime = (int64_t)(LastAccessTime / 10000000); - timbuf.modtime = (int64_t)(LastWriteTime / 10000000); -#else - timbuf.actime = (int32_t)(LastAccessTime / 10000000); - timbuf.modtime = (int32_t)(LastWriteTime / 10000000); -#endif - + timbuf.actime = tv[0].tv_sec; + timbuf.modtime = tv[1].tv_sec; err = f->ops.utime(filedesc->PosixPath, &timbuf); Result = fsp_fuse_ntstatus_from_errno(f->env, err); }