chronospoon
chronospoon

Reputation: 637

Modifying post-2040 macOS file creation/modification dates

In my Synology NAS, I have an APFS share with files that have been transferred back and forth for decades across different OSes.

For files that were copied via NFS originally, and now hosted via AFP, all the file dates seem to be offset by some amount. I can sort of eyeball the datetime offset, but is there a definitive number I can use? (And a simple way to parse/modify the times using something like GetFileInfo?)

Upvotes: -1

Views: 208

Answers (2)

chronospoon
chronospoon

Reputation: 637

It appears that when setting the creation date with macOS's GetFileInfo -d/SetFile -d, then rsyncing that to an AFP mount, Synology DiskStation interprets that field as the "Last Accessed" date.

Which is fine and consistent up until you modify something from within DiskStation, at which point it updates the "Last Accessed" timestamp, which propagates back into macOS's "Date Created" field.

So the timestamps likely have no relation; it's that DiskStation ends up updating ctime every time it accesses the file. This is still happening with macOS 14.7 + Synology DiskStation 7.2; workaround is to just never modify files from "File Station" (in the DiskStation web portal). (AFP has been deprecated for a long time, so this is unlikely to be fixed.)

Upvotes: 0

chronospoon
chronospoon

Reputation: 637

This seems to be something related to 32-bit and 64-bit overflows, somewhere in this complicated storage stack; the way the datetimes + error offsets add up is consistently close to 2^31, though I wasn't able to find any clear pattern.

Also, I noticed strange behavior from my Synology system's use of eCryptFS, which seems to lag metadata updates when done in batch. (In particular, I suspect that some eCryptFS/Synology metadata is getting translated incorrectly, or just never written to disk.)


Anyway, I basically wrote a Python script that does the following:

  • check if os.stat() reports an atime/mtime newer than 2030
  • check that both atime and mtime are newer; error out if they differ
  • adjust both times back by 632599096 seconds (offset based on comparing copies of the one file I found in common between two systems).

with the following caveats to watch out for:

  • macOS's GetFileInfo/SetFile utilities only support 32-bit datetimes, so you should generally avoid using them (even just to verify the metadata updates).
  • something in the Synology/eCryptFS encryption gets very slow, so after a few dozen metadata updates, the updates will no longer be visible (even after calling sync from the shell). But if you give it some time, you'll see the corrected atime/mtime changes.
  • The OS-specific os.stat field, ctime, does literally track metadata update times. And there doesn't seem to be a way to manually set it (nor a need to, since this isn't visible through any GUI).

The combination of slow metadata updates + GetFileInfo reporting the wrong time made this incredibly frustrating, until I figured both out. In practice, this means you have to test metadata updates on a few files at a time, then your large batch execution can only be verified a few hours later (I waited a day).

This should have been a blog post, good riddance.

Upvotes: 0

Related Questions