Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I was just reading up on the Birth section of stat and it appears ext4 should support it, but even a file I just created leaves it empty.

 ~  % touch test                                                       slave-iv
 ~  % stat test.pl                                                     slave-iv
  File: ‘test.pl’
  Size: 173             Blocks: 8          IO Block: 4096   regular file
Device: 903h/2307d      Inode: 41943086    Links: 1
Access: (0600/-rw-------)  Uid: ( 1000/xenoterracide)   Gid: (  100/   users)
Access: 2012-09-22 18:22:16.924634497 -0500
Modify: 2012-09-22 18:22:16.924634497 -0500
Change: 2012-09-22 18:22:16.947967935 -0500
 Birth: -

 ~  % sudo tune2fs -l /dev/md3 | psp4                                  slave-iv
tune2fs 1.42.5 (29-Jul-2012)
Filesystem volume name:   home
Last mounted on:          /home
Filesystem UUID:          ab2e39fb-acdd-416a-9e10-b501498056de
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    journal_data
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              59736064
Block count:              238920960
Reserved block count:     11946048
Free blocks:              34486248
Free inodes:              59610013
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      967
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
RAID stride:              128
RAID stripe width:        256
Flex block group size:    16
Filesystem created:       Mon May 31 20:36:30 2010
Last mount time:          Sat Oct  6 11:01:01 2012
Last write time:          Sat Oct  6 11:01:01 2012
Mount count:              14
Maximum mount count:      34
Last checked:             Tue Jul 10 08:26:37 2012
Check interval:           15552000 (6 months)
Next check after:         Sun Jan  6 07:26:37 2013
Lifetime writes:          7255 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
First orphan inode:       55313243
Default directory hash:   half_md4
Directory Hash Seed:      442c66e8-8b67-4a8c-92a6-2e2d0c220044
Journal backup:           inode blocks

Why doesn't my ext4 partition populate this field?

share|improve this question
Sadly, this is still not implemented because the xstat() kernel interface is being bikeshedded: lwn.net/Articles/686106 – A.Danischewski Jul 13 at 16:03
up vote 31 down vote accepted

The field gets populated (see below) only coreutils stat does not display it. Apparently they're waiting1 for the xstat() interface.

coreutils patches - aug. 2012 - TODO

stat(1) and ls(1) support for birth time. Dependent on xstat() being provided by the kernel

You can get the creation time via debugfs:

debugfs -R 'stat <inode_number>' DEVICE

e.g. for my /etc/profile which is on /dev/sda2 (see How to find out what device a file is on):

stat -c %i /etc/profile
debugfs -R 'stat <398264>' /dev/sda2
debugfs 1.42.5 (29-Jul-2012)
Inode: 398264   Type: regular    Mode:  0644   Flags: 0x80000
Generation: 2058737571    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 562
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x506b860b:19fa3c34 -- Wed Oct  3 02:25:47 2012
 atime: 0x50476677:dcd84978 -- Wed Sep  5 16:49:27 2012
 mtime: 0x506b860b:19fa3c34 -- Wed Oct  3 02:25:47 2012
crtime: 0x50476677:dcd84978 -- Wed Sep  5 16:49:27 2012
Size of extra inode fields: 28

1 Linus' reply on LKML thread

share|improve this answer
sudo debugfs -R 'stat /path/to/foo' /dev/sda2 gives me /path/to/foo: File not found by ext2_lookup. stat /path/to/foo works (with Birth empty). Also, ext2? – Sparhawk Nov 9 '13 at 3:01
@Sparhawk: I had this problem too with a file /home/user/path/to/file because /home was on a separate partition. In that case, the path provided to stat must be relative to /home. Example: sudo debugfs -R 'stat user/path/to/file' /dev/sda2. To get rid of the path handling, we can provide to stat the inode number instead of the path: sudo debugfs -R "stat <$(stat -c %i /home/user/path/to/file)>" /dev/sda5 – jpfleury Apr 17 '14 at 2:39
@jpfleury Thanks. That works now. – Sparhawk May 1 '14 at 1:13
Equivalent of stat /home/richard is sudo debugfs -R 'stat /richard' /dev/disk/by-label/home — assuming that /home is a separate file-system, and you file-systems are labelled. – richard Aug 11 '14 at 11:27
@jpfleury My situation is like yours with a separation home partition. I can get the creation time by your method. But I don't know why. For example, home partition is sda5, and current directory is ~, and I want to get crtime of file.txt under ~. I use sudo debugfs -R 'stat file.txt' /dev/sda5. Why debufs cannot find the file.txt on sda5? – Zachary Sep 16 '14 at 11:17

I combined this into a simple shell function:

get_crtime() {

  for target in "${@}"; do
    inode=$(stat -c %i "${target}")
    fs=$(df  --output=source "${target}"  | tail -1)
    crtime=$(sudo debugfs -R 'stat <'"${inode}"'>' "${fs}" 2>/dev/null | 
    grep -oP 'crtime.*--\s*\K.*')
    printf "%s\t%s\n" "${target}" "${crtime}"

You can then run it with

$ get_crtime foo foo/file /etc/
foo Wed May 21 17:11:08 2014
foo/file    Wed May 21 17:11:27 2014
/etc/   Wed Aug  1 20:42:03 2012
share|improve this answer
is there a particular reason for not using inode=$(stat -c %i "${target}") instead? It's easier and simpler.. – yat0 Oct 10 '15 at 17:33
@BrunoCasteleiro basically because that was the one that occurred to me and I like the chance to safely parse ls. It doesn't happen often :). You're right though, stat is probably better, thanks. – terdon Oct 12 '15 at 11:39

There's another case where Birth time will be empty/zero/dash: Ext4's Inode size has to be at least 256bytes to store crtime. The problem occur if you initially created the filesystem smaller than 512MB ( the default Inode size will be 128 bytes, see /etc/mke2fs.conf and mkfs.ext4 manpage).

stat -c '%n: %w' testfile
testfile: -  


stat -c '%n: %W' testfile
testfile: 0

Now check the filesystem inode (is it big enough to store crtime?):

tune2fs -l $(df . --output=source | grep ^/) | grep "Inode size:"
Inode size:           128

Technical information: On the Ext4 Disk Layout page, note that some attributes of the inode tables are beyond 0x80 (128).

share|improve this answer
Correct (I remember reading about this on vger). The 512MB limit is defined in mke2fs.c at line 1275 – don_crissti Mar 27 '15 at 23:22

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.