Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

41226928: APFS mtime timestamp numeric precision (rounding) error #19944

Open
openradar-mirror opened this issue Jun 18, 2018 · 0 comments
Open

Comments

@openradar-mirror
Copy link

Description

Summary:

APFS (presumably the driver) on macOS 10.13 (up to an including at least 10.13.5 (17F77)) has a numeric precision / rounding error for file modification & other file metadata timestamps.

I am unsure (due to a lack of syscall source code on macOS) if this is a bug in the utime(2) call itself as implemented in macOS 10.13, or the APFS driver, but the driver seems more likely to me (since the syscall is relatively un-complex and not at all new).

This same bug was also reported from the Ruby programming language, and the openradar report of it is the only way I was able to decisively narrow this down:
http://www.openradar.me/33734892 or #18144

I can confirm that this is reproducible using only C syscalls.

Steps to Reproduce:

I have isolated one of the numeric values that causes incorrect precision handling / rounding, 1529011085547.0, from various test sources.

This value always causes this problem on only macOS 10.13, using APFS. macOS 10.12 and lower, other BSD platforms, linuxes, Windows, etc, do not have this issue. (AIX appears to also have the issue, but... oh well.)

When this value is sent to utime(2) (for either atime, mtime, or both), the respective value as read from the file metadata in stat(2) will no longer be what it was set to, and instead somehow ends up being 9223372036.854776

In my case, this patch to the libuv cross-platform I/O library written in C always reproduces this issue in it's tests: Fishrock123/libuv@29527a8

Here is a test run from the libuv project's infrastructure showing platforms which it does and does not fail on: https://ci.nodejs.org/view/libuv/job/libuv-test-commit/929/ (Some test failures are from other tests, and not every failure if from this patch.)

Attached is a C-only version. Compile it by running cc apfs-precision-error.c and then run the created a.out to get comparison output.

Expected Results:

After setting the mtime to 1529011085547.0 using utime(2)
stat(2) should return mtime values that equal 1529011085547.0

Actual Results:

After setting the mtime to 1529011085547.0 using utime(2)
stat(2) returns mtime values that equal 9223372036.854776

Version/Build:

10.13.5 (17F77)

Configuration:

Default configuration macOS 10.13 on colleagues' computers seems to also reproduce this always.

apfs-precision-error.c

#include <stdio.h>
#include <sys/stat.h>
#include <utime.h>
#include <fcntl.h>

const char* path = "./.temp";
const double controlValue = 1529011085547.0;

int main(int argc, const char *argv[])
{
    open(path, O_CREAT);

    struct utimbuf buf;
    buf.actime = controlValue;
    buf.modtime = controlValue;
    utime(path, &buf);

    struct stat s;
    stat(path, &s);

    double converted_atime = (unsigned long)s.st_atimespec.tv_sec + (s.st_atimespec.tv_nsec / 1000000000.0);
    double converted_mtime = (unsigned long)s.st_mtimespec.tv_sec + (s.st_mtimespec.tv_nsec / 1000000000.0);

    printf("atime - Actual: %f, Expected: %f\n", converted_atime, controlValue);
    printf("mtime - Actual: %f, Expected: %f\n", converted_mtime, controlValue);
}

Product Version: 10.13.5 (17F77)
Created: 2018-06-18T22:21:36.840330
Originated: 2018-06-18T00:00:00
Open Radar Link: http://www.openradar.me/41226928

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

1 participant