eden: add helper for accessing stat fields as timespecs

Summary:
ported forward from D4209167, add a couple of helpers
to access these fields on mac and linux, centralizing/minimizing ifdefs.

Simplify some of the logic in FileChangeMonitor.

Reviewed By: chadaustin

Differential Revision: D13475717

fbshipit-source-id: d7b39999808bc41a6dc17a87189501cb34e68b30
This commit is contained in:
Wez Furlong 2018-12-16 18:29:52 -08:00 committed by Facebook Github Bot
parent 5b08e0c73b
commit 3dbcd058d6
6 changed files with 81 additions and 18 deletions

View File

@ -15,22 +15,21 @@
#ifdef EDEN_WIN
#include "eden/win/fs/utils/Stub.h" // @manual
#endif
#include "eden/fs/utils/StatTimes.h"
#include "eden/fs/utils/TimeUtil.h"
namespace facebook {
namespace eden {
bool equalStats(const struct stat& stat1, const struct stat& stat2) noexcept {
return (
stat1.st_dev == stat2.st_dev && stat1.st_size == stat2.st_size &&
return stat1.st_dev == stat2.st_dev && stat1.st_size == stat2.st_size &&
stat1.st_ino == stat2.st_ino && stat1.st_mode == stat2.st_mode &&
#ifdef EDEN_WIN
stat1.st_ctime == stat2.st_ctime && stat1.st_mtime == stat2.st_mtime);
stat1.st_ctime == stat2.st_ctime && stat1.st_mtime == stat2.st_mtime
#else
stat1.st_ctim.tv_sec == stat2.st_ctim.tv_sec &&
stat1.st_ctim.tv_nsec == stat2.st_ctim.tv_nsec &&
stat1.st_mtim.tv_sec == stat2.st_mtim.tv_sec &&
stat1.st_mtim.tv_nsec == stat2.st_mtim.tv_nsec);
stCtime(stat1) == stCtime(stat2) && stMtime(stat1) == stMtime(stat2)
#endif
;
}
AbsolutePath FileChangeMonitor::getFilePath() {
return filePath_;

View File

@ -134,12 +134,8 @@ class FileChangeMonitor {
// Set values for stat to force changedSinceUpdate() to return TRUE.
// We use a novel setting to force change to be detected
memset(&fileStat_, 0, sizeof(struct stat));
#ifdef EDEN_WIN
fileStat_.st_mtime = 1;
#else
fileStat_.st_mtim.tv_sec = 1;
fileStat_.st_mtim.tv_nsec = 1;
#endif
statErrno_ = 0;
openErrno_ = 0;
// Set lastCheck in past so throttle does not apply.

View File

@ -17,6 +17,7 @@
#include "eden/fs/fuse/FileHandle.h"
#include "eden/fs/fuse/RequestData.h"
#include "eden/fs/utils/StatTimes.h"
using namespace folly;
using namespace std::chrono;
@ -34,11 +35,11 @@ fuse_attr_out Dispatcher::Attr::asFuseAttr() const {
result.attr.size = st.st_size;
result.attr.blocks = st.st_blocks;
result.attr.atime = st.st_atime;
result.attr.atimensec = st.st_atim.tv_nsec;
result.attr.atimensec = stAtime(st).tv_nsec;
result.attr.mtime = st.st_mtime;
result.attr.mtimensec = st.st_mtim.tv_nsec;
result.attr.mtimensec = stMtime(st).tv_nsec;
result.attr.ctime = st.st_ctime;
result.attr.ctimensec = st.st_ctim.tv_nsec;
result.attr.ctimensec = stCtime(st).tv_nsec;
result.attr.mode = st.st_mode;
result.attr.nlink = st.st_nlink;
result.attr.uid = st.st_uid;

View File

@ -149,7 +149,11 @@ void InodeTimestamps::setattrTimes(
}
void InodeTimestamps::applyToStat(struct stat& st) const {
#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
#ifdef __APPLE__
st.st_atimespec = atime.toTimespec();
st.st_ctimespec = ctime.toTimespec();
st.st_mtimespec = mtime.toTimespec();
#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
st.st_atim = atime.toTimespec();
st.st_ctim = ctime.toTimespec();

View File

@ -56,6 +56,7 @@
#include "eden/fs/store/ObjectStore.h"
#include "eden/fs/tracing/Tracing.h"
#include "eden/fs/utils/ProcUtil.h"
#include "eden/fs/utils/StatTimes.h"
using folly::Future;
using folly::makeFuture;
@ -705,8 +706,9 @@ EdenServiceHandler::future_getFileInformation(
return inode->getattr().thenValue([](Dispatcher::Attr attr) {
FileInformation info;
info.size = attr.st.st_size;
info.mtime.seconds = attr.st.st_mtim.tv_sec;
info.mtime.nanoSeconds = attr.st.st_mtim.tv_nsec;
auto& ts = stMtime(attr.st);
info.mtime.seconds = ts.tv_sec;
info.mtime.nanoSeconds = ts.tv_nsec;
info.mode = attr.st.st_mode;
FileInformationOrError result;

61
eden/fs/utils/StatTimes.h Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#pragma once
#include <stdint.h>
#include <time.h>
namespace facebook {
namespace eden {
#ifndef _WIN32
/** Helper for accessing the `atime` field of a `struct stat` as a timespec.
* Linux and macOS have different names for this field. */
inline const struct timespec& stAtime(const struct stat& st) {
#ifdef __APPLE__
return st.st_atimespec;
#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
return st.st_atim;
#else
#error teach this system how to get the stat change time as a timespec
#endif
}
/** Helper for accessing the `mtime` field of a `struct stat` as a timespec.
* Linux and macOS have different names for this field. */
inline const struct timespec& stMtime(const struct stat& st) {
#ifdef __APPLE__
return st.st_mtimespec;
#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
return st.st_mtim;
#else
#error teach this system how to get the stat modify time as a timespec
#endif
}
/** Helper for accessing the `ctime` field of a `struct stat` as a timespec.
* Linux and macOS have different names for this field. */
inline const struct timespec& stCtime(const struct stat& st) {
#ifdef __APPLE__
return st.st_ctimespec;
#elif defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700
return st.st_ctim;
#else
#error teach this system how to get the stat change time as a timespec
#endif
}
#endif
} // namespace eden
} // namespace facebook