3

I copy some directories with -a in order to preserve=all which I understood would include creation times:

cp -a ./* /mnt/destination/

When inspecting the resulting directories in the destination they all have creation time set to the current time, while their contents seem to have preserved their creation times.

Why aren't the creation dates of the top level directories preserved?

The source is HFS+ and the destination is btrfs.


Excerpts of directory listings of destination and source:

$ ls -hal --time=creation
total 16K
drwxrwxr-x 1 andreas andreas   74 sep  2 23:25  .
drwx------ 1 andreas andreas  310 apr 26 17:08  ..
drwx------ 1 andreas andreas 2,3K sep  2 23:45  Library

$ ls -hal --time=creation /mnt/source
total 8,1M
drwxrwxr-x  1 andreas andreas   15 mar 28  2022  .
drwxr-x---+ 3 root    root    4,0K aug  9  2022  ..
drwx------  1 andreas andreas   95 apr 15  2019  Library

Update

Judging by the answers and comments I concluded that I must have made a mistake when I inspected the dates of subdirectories. I did. My fault — my expectations of the result blinded me of what I was looking at. That part of the question has been dropped.

4
  • 1
    Please edit your question and show us how you are checking creation times. Ideally, show us what you are copying, where from, and where to, so we can try and reproduce locally. Are you sure you're not looking at modification time which will be changed since you just moved something into those directories?
    – terdon
    Commented Sep 2, 2023 at 22:47
  • @terdon Thanks. I added ls outputs. The first indicator was in the "Created" column in Ubuntu's Files app though. Not sure of the exact details needed to recreate it, but it's from files copied by macOS to a HFS+ formatted USB stick to btrfs on a USB attached HDD, using Ubuntu 23.04 on a Raspberry Pi 4. The example shows my macOS user's Library directory copied "exactly" by macOS Ventura's Finder onto the source volume.
    – Andreas
    Commented Sep 2, 2023 at 23:22
  • To preserve times, perhaps use rsync instead: rsync -a ./ /mnt/destination/
    – D McKeon
    Commented Sep 2, 2023 at 23:33
  • @DMcKeon Thanks for the tip. I mostly want to clear up potential gaps in my understanding, since I think it would be convenient to have confidence in cp as well.
    – Andreas
    Commented Sep 2, 2023 at 23:38

2 Answers 2

10

Traditional unix filesystems don't have creation time, only ctime. ctime is change time, not creation time. Change time can't be set via OS calls except to change it to the current time. Changing permissions or changing atime or mtime will set ctime to the current time.

Having said that, it seems that even though creation time is not part of POSIX, many filesystems seem to have added it, see What file systems on Linux store the creation time?

However, even for filesystems that support it, it isn't standardized, so support for creation time in POSIX tools is not guaranteed, and even on filesystems that support it, it may not be set. If you are seeing it set some times and not others, or not consistently set, possibly multiple tools with varying support are involved, or there is only partial support in those tools.

The linux specific statx function call supports atime, btime, ctime, and mtime, where btime is marked as creation time. However, this only reads the times. (Note that various filesystems reference creation time in various ways including birthtime btime crtime and otime.)

Digging deeper, gnu coreutils cp documents setting time via the utimensat function call, which claims POSIX-1.2008 conformance. This call only supports modifying atime and mtime but researching this, I could not determine if this is because POSIX only supports atime and mtime (with ctime not settable), or if it is because both ctime and btime are basically immutable, changes only allowed by the operating system, setting them to the current time at the appropriate events.

9
  • Thanks. If we assume creation times do not actually exist on btrfs, or even if there's just no api to set it, then it's still inexplicable how the contents of the directories had their same time stamp fields (time=creation in ls) set to the actual original dates (i.e. years ago) during the copy. If I understood you right, these times should also have been set to the current time. I would have expected cp to be consistent with the same field.
    – Andreas
    Commented Sep 2, 2023 at 23:29
  • 1
    btrfs might be one of the ones that has a creation time. It is possible that cp doesn't know how to set it.
    – user10489
    Commented Sep 3, 2023 at 1:31
  • 1
    It could also be a bug in cp. But considering that POSIX doesn't support creation time, it's surprising if cp does anything with it.
    – user10489
    Commented Sep 3, 2023 at 4:12
  • 1
    POSIX specifies a minimal set of features, there is no operating system which only implements POSIX. It’s common for “POSIX” tools such as cp to support more features than specified in POSIX. However as far as I‘m aware there’s no way of changing a file’s creation time after its creation. Commented Sep 3, 2023 at 8:00
  • 1
    My point is that any features that are not POSIX are implemented inconsistently at best and the semantics of creation date are not defined for linux.
    – user10489
    Commented Sep 3, 2023 at 13:40
4

The only time stamps that can be set to arbitrary values (using the utime(), utimes(), utimensat(), futimens() system calls) are the last modification time aka mtime and last access time aka atime.

The change status time aka ctime and birth/creation time (btime/crtime) where supported can't be faked (set arbitrarily), so cp -a, like any other software cannot create a file with a birth time other than that corresponding to the time it was created.

Doing a ln foo bar inplace of cp foo bar or using the -l option of GNU cp would result in bar having the same timestamps including creation time as foo, but note that in that case, foo and bar are the same file (with two different names).

4
  • 1
    creation time is "crtime" on some filesystems. Other filesystems might use a different name in the data structure. It isn't standard and it isn't consistently implemented.
    – user10489
    Commented Sep 3, 2023 at 13:47
  • 2
    @KamilMaciorowski I think you're supposed read "birth/creation time" as one concept, represented by multiple field names "crtime, btime". As a one-to-many relationship the mismatch goes away.
    – Andreas
    Commented Sep 3, 2023 at 13:54
  • 2
    @Andreas Kamil's point is that since it says "birth/creation", the parenthesis should say "btime/crtime" to match that order (or vice versa), instead of the current "crtime/btime"
    – muru
    Commented Sep 3, 2023 at 14:52
  • I'm pretty sure that software installers on MacOS preserve the creation time from the original site. This requires "faking" it when installing on the target.
    – Barmar
    Commented Sep 3, 2023 at 19:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .