File Creation Time in Linux

The stat utility can be used to retrieve the Unix file timestamps namely atime , ctime and mtime . Of these, the benefit of mtime which records the last time when the file was modified is immediately apparent. On the other hand, atime which records the last time the file was accessed has been called “perhaps the most stupid Unix design idea of all times”. Intuitively, one might expect ctime to record the creation time of a file. However, ctime records the last time when the metadata of a file was changed.

Typically, Unices do not record file creation times. While some individual filesystems do record file creation times, until recently Linux lacked a common interface to actually expose them to userspace applications. As a result, the output of stat (GNU coreutils v8.30) on an ext4 filesystem (Which does record creation times) looks something like this:

$ stat . File: . Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 803h/2051d Inode: 3588416 Links: 18 Access: ( 0775/drwxrwxr-x ) Uid: ( 1000/ anmol ) Gid: ( 1000/ anmol ) Access: 2019-06-23 10:49:04.056933574 +0000 Modify: 2019-05-19 13:29:59.609167627 +0000 Change: 2019-05-19 13:29:59.609167627 +0000 Birth: -

With the “ Birth ” field, meant to show the creation time, sporting a depressing “ - ”.

The fact that ctime does not mean creation time but change time coupled with the absence of a real creation time interface does lead to quite a bit of confusion. The confusion seems so pervasive that the msdos driver in the Linux kernel happily clobbers the FAT creation time with the Unix change time!

The limitations of the current stat() system call have been known for some time. A new system call providing extended attributes was first proposed in 2010 with the new statx() interface finally being merged into Linux 4.11 in 2017. It took so long at least in part because kernel developers quickly ran into one of the hardest problems in Computer Science: naming things. Because there was no standard to guide them, each filesystem took to calling creation time by a different name. Ext4 and XFS called it crtime while Btrfs and JFS called it otime . Implementations also have slightly different semantics with JFS storing creation time only with the precision of seconds.

Glibc took a while to add a wrapper for statx() with support landing in version 2.28 which was released in 2018. Fast forward to March 2019 when GNU coreutils 8.31 was released with stat finally gaining support for reading the file creation time:

$ stat . File: . Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 803h/2051d Inode: 3588416 Links: 18 Access: ( 0775/drwxrwxr-x ) Uid: ( 1000/ anmol ) Gid: ( 1000/ anmol ) Access: 2019-06-23 10:49:04.056933574 +0000 Modify: 2019-05-19 13:29:59.609167627 +0000 Change: 2019-05-19 13:29:59.609167627 +0000 Birth: 2019-05-19 13:13:50.100925514 +0000