[llvm-bugs] [Bug 35990] New: std::experimental::filesystem::file_time_type::min() exceeds values supported by the underlying file system
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Jan 17 12:18:34 PST 2018
https://bugs.llvm.org/show_bug.cgi?id=35990
Bug ID: 35990
Summary: std::experimental::filesystem::file_time_type::min()
exceeds values supported by the underlying file system
Product: libc++
Version: unspecified
Hardware: PC
OS: All
Status: NEW
Severity: normal
Priority: P
Component: All Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: vsapsai at apple.com
CC: eric at efcs.ca, llvm-bugs at lists.llvm.org,
mclow.lists at gmail.com
Created attachment 19698
--> https://bugs.llvm.org/attachment.cgi?id=19698&action=edit
Code to test with low-level API.
std::experimental::filesystem::file_time_type::min() exceeds values supported
by the underlying file system. When you set file modification time with
filesystem::last_write_time(path, time) with min value and read it back with
filesystem::last_write_time(path), received value can be significantly
different from the supplied one.
Steps to reproduce:
1. Call
auto min_time = std::experimental::filesystem::file_time_type::min();
std::experimental::filesystem::last_write_time(path, min_time);
2. Call
auto current_time = std::experimental::filesystem::last_write_time(path);
3. Reboot machine you are running the test on.
4. Call
auto current_time2 = std::experimental::filesystem::last_write_time(path);
Expected result:
min_time, current_time, current_time2 should be equal, at least to the second.
Actual result:
Results depend on the underlying file system.
On macOS with APFS min_time != current_time, current_time == current_time2.
Inequality is detected by the test
std/experimental/filesystem/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp
On Ubuntu 16.04.3 with ext3 min_time == current_time, current_time !=
current_time2.
Details:
For writing and reading file modification timestamp we are using utimensat and
stat, respectively. In my testing filesystem::file_time_type::min() was -2^63
microseconds which can be expressed with `struct timespec` which has 64-bit
tv_sec and 64-bit tv_nsec. But file systems I tested don't use 128 bits to
store timestamps on the disk. One common approach seems to be using 128-bit
value while inode metadata is still in memory. That allows the test
last_write_time.pass.cpp to pass on ext3 and probably ext4. But according to
POSIX.1-2008 http://pubs.opengroup.org/onlinepubs/9699919799/ that is not
conformant
> Upon assignment, file timestamps are immediately converted to the resolution
> of the file system by truncation (i.e., the recorded time can be older than
> the actual time). For example, if the file system resolution is 1
> microsecond, then a conforming stat() must always return an st_mtim.tv_nsec
> that is a multiple of 1000. Some older implementations returned
> higher-resolution timestamps while the inode information was cached, and then
> spontaneously truncated the tv_nsec fields when they were stored to and
> retrieved from disk, but this behavior does not conform.
> - Section 11. Headers, <sys/stat.h>
Regardless of the POSIX standard, I think the developers expect that values in
file_time_type::min()/max() range are safe to use and won't change on their
own.
I have attached `testing.c` to test utimensat and stat directly and the results
are
On APFS:
Will update file mtime to
tv_sec = -9223372036854,
tv_nsec = 0
File mtime now is
tv_sec = -9223372036,
tv_nsec = -854775808
On ext3:
Will update file mtime to
tv_sec = -9223372036854,
tv_nsec = 0
File mtime now is
tv_sec = -9223372036854,
tv_nsec = 0
after rebooting
File mtime now is
tv_sec = 2217714954,
tv_nsec = 0
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180117/d0069dcb/attachment.html>
More information about the llvm-bugs
mailing list