[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Creation vs Modification timestamps



On Sat, Jun 12, 2021 at 02:43:22AM -0400, Polyna-Maude Racicot-Summerside wrote:
> If you look at the specifications for all the different "ext2/3/4"
> filesystem specifications, there's no place it says "store all the
> passed date possible". What you see in ls -l is what's in the inode.
> There's no secret hidden place with the dates of the file.

This is incorrect.


On Sat, Jun 12, 2021 at 06:46:44AM -0400, Dan Ritter wrote:
> No. There are three timestamps, and none of them are original
> creation times.
> 
> atime is last access time, and most modern systems have either
> stopped recording this, or set it only when mtime is written.
> 
> mtime is last modification time, or if you prefer, the last time
> it was written to.
> 
> ctime is not creation time; it is the last time the inode was
> changed. ctime is updated when the permissions or ownership of
> the file changes, or the number of links changes, or the number
> of blocks changes...

Those are the POSIX file system semantics.  If you only look at the *sane*
parts of the Linux APIs, then that's all you'll be able to work with.
It's certainly all that's guaranteed across the various Unix-type file
systems.

However, ext4 actually *does* store a creation time.  It's hidden in a
field that isn't exposed via the normal stat(2) interface.  Virtually none
of the standard userland tools are able to see it.

On bullseye, stat(1) has been altered to make "birth" (a.k.a. creation)
time visible.  Here's a demonstration.  My home directory is on an ext4
file system with these mount options:

/dev/sda8 on /home type ext4 (rw,relatime)

unicorn:~$ rm x
unicorn:~$ echo x > x
unicorn:~$ sleep 5; chmod 600 x
unicorn:~$ stat x
  File: x
  Size: 2         	Blocks: 8          IO Block: 4096   regular file
Device: 808h/2056d	Inode: 803372      Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/    greg)   Gid: ( 1000/    greg)
Access: 2021-06-12 08:53:06.179415149 -0400
Modify: 2021-06-12 08:53:06.179415149 -0400
Change: 2021-06-12 08:53:20.391429504 -0400
 Birth: 2021-06-12 08:53:06.179415149 -0400

The "Change" line (ctime) is updated when the chmod runs, but the "Birth"
line is not.

unicorn:~$ echo y >> x
unicorn:~$ stat x
  File: x
  Size: 4         	Blocks: 8          IO Block: 4096   regular file
Device: 808h/2056d	Inode: 803372      Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/    greg)   Gid: ( 1000/    greg)
Access: 2021-06-12 08:53:06.179415149 -0400
Modify: 2021-06-12 08:53:40.787450117 -0400
Change: 2021-06-12 08:53:40.787450117 -0400
 Birth: 2021-06-12 08:53:06.179415149 -0400

Writing to the file updates the mtime and ctime fields, but not Birth.

Now, the bad news: if you're on buster or older, this won't work.  The
tools to work with ext4's Birth field simply didn't exist, or didn't
work.  And if you're on ext3 or many other file systems, these fields
simply don't exist in the file system, so it won't matter what tools
you use.

If you search the web, you can find other approaches to extracting the
Birth field on ext4 without working userland tools.  Many of them involve
running debugfs with sudo.  I wouldn't recommend doing this, other than
once as a proof of concept just to see that it does in fact "work".

The top answer on
<https://unix.stackexchange.com/questions/91197/how-to-find-creation-date-of-file>
gives some detailed explanations of how ugly this whole thing truly is.


Reply to: