File Creation Time in Linux
Jun 23, 2019 tech linux filesystemThe 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
1 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 times2, 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