Birth is empty on ext4 Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election Results Why I closed the “Why is Kali so hard” questionGetting file crtime under ext4 file systemWhy is time of birth of file unknown?Get file created/creation time?How do I do a ls and then sort the results by date created?Changing a file's “Date Created” and “Last Modified” attributes to another file'sWhat file systems on Linux store the creation time?How to reliably get timestamp at which the system booted?How to find what device a file is on (and use that in a script)?Does Linux have system calls to access all the features of the file systems it supports?Find the time of the file received in a particular directoryext4 used space (not -m option, not deleted files)Disk problems prevent me from booting, or set the disk to read-only. How do I fix the disk?Ext2 block structure: size of reserved GDT BlocksDisk usage in stat output and inodeFilesystem errors when restoring many filesPartition Errors and Remounts Read-Only when Accessing Specific FileIs the slash (/) part of the name of the Linux root directory?How to calculate the correct size of a loopback device filesystem image for debootstrap?I/O error after power failure, filesystem remounting as read-onlyHow to use ext4 inline_data to store empty directories?

What are the performance impacts of 'functional' Rust?

Typsetting diagram chases (with TikZ?)

How to set letter above or below the symbol?

Why don't the Weasley twins use magic outside of school if the Trace can only find the location of spells cast?

Who can trigger ship-wide alerts in Star Trek?

What is the order of Mitzvot in Rambam's Sefer Hamitzvot?

What do I do if technical issues prevent me from filing my return on time?

Did the new image of black hole confirm the general theory of relativity?

Stop battery usage [Ubuntu 18]

What did Darwin mean by 'squib' here?

Determine whether f is a function, an injection, a surjection

Why does tar appear to skip file contents when output file is /dev/null?

Slither Like a Snake

Why is there no army of Iron-Mans in the MCU?

How should I respond to a player wanting to catch a sword between their hands?

How is simplicity better than precision and clarity in prose?

What is the electric potential inside a point charge?

Direct Experience of Meditation

90's book, teen horror

Is it possible to ask for a hotel room without minibar/extra services?

Can a monk deflect thrown melee weapons?

Cauchy Sequence Characterized only By Directly Neighbouring Sequence Members

How to politely respond to generic emails requesting a PhD/job in my lab? Without wasting too much time

What to do with post with dry rot?



Birth is empty on ext4



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionGetting file crtime under ext4 file systemWhy is time of birth of file unknown?Get file created/creation time?How do I do a ls and then sort the results by date created?Changing a file's “Date Created” and “Last Modified” attributes to another file'sWhat file systems on Linux store the creation time?How to reliably get timestamp at which the system booted?How to find what device a file is on (and use that in a script)?Does Linux have system calls to access all the features of the file systems it supports?Find the time of the file received in a particular directoryext4 used space (not -m option, not deleted files)Disk problems prevent me from booting, or set the disk to read-only. How do I fix the disk?Ext2 block structure: size of reserved GDT BlocksDisk usage in stat output and inodeFilesystem errors when restoring many filesPartition Errors and Remounts Read-Only when Accessing Specific FileIs the slash (/) part of the name of the Linux root directory?How to calculate the correct size of a loopback device filesystem image for debootstrap?I/O error after power failure, filesystem remounting as read-onlyHow to use ext4 inline_data to store empty directories?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








75















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




























    75















    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
























      75












      75








      75


      40






      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














      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?







      filesystems ext4 stat






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Oct 8 '12 at 3:48









      xenoterracidexenoterracide

      26.2k54159222




      26.2k54159222




















          5 Answers
          5






          active

          oldest

          votes


















          81














          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
          398264


          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
          EXTENTS:
          (0):3308774


          1Linus' 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






          • 4





            @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











          • 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.

            – ctrl-alt-delor
            Aug 11 '14 at 11:27







          • 2





            Can this be used to get creation time of files from a network-mounted filesystem?

            – taranaki
            Sep 20 '18 at 18:32






          • 1





            So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

            – sinekonata
            Mar 1 at 3:10


















          27














          I combined this into a simple shell function:



          get_crtime() 
          grep -oP 'crtime.*--s*K.*')
          printf "%st%sn" "$target" "$crtime"
          done



          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






          • 1





            Thanks for having all the steps combined into one function.

            – WinEunuuchs2Unix
            Dec 23 '18 at 18:38


















          14














          The xstat function never got merged into mainline. However, a new statx call was proposed later on, and was merged in Linux 4.11. The new statx(2) system call does include a creation time in its return struct.



          However, userland has yet to catch up - it's not easy to call system calls directly in a C program. Typically glibc provides a wrapper that makes the job easy, but glibc added a wrapper for statx(2) only in 2.28 (release August 2018). Luckily, @whotwagner wrote a sample C program that shows how to use the statx(2) system call on x86 and x86-64 systems. Its output is the same format as stat's default, without any formatting options, but it's simple to modify it to print just the birth time. (If you have a new enough glibc, you won't need this - you can use statx directly as described in man 2 statx).



          First, clone it:



          git clone https://github.com/whotwagner/statx-fun


          You can compile the statx.c code, or, if you just want the birth time, create a birth.c in the cloned directory with the following code (which is a minimal version of statx.c printing just the creation timestamp including nanosecond precision):



          #define _GNU_SOURCE
          #define _ATFILE_SOURCE
          #include <stdio.h>
          #include <stdlib.h>
          #include <sys/types.h>
          #include <unistd.h>
          #include <fcntl.h>
          #include "statx.h"
          #include <time.h>
          #include <getopt.h>
          #include <string.h>

          // does not (yet) provide a wrapper for the statx() system call
          #include <sys/syscall.h>

          /* this code works ony with x86 and x86_64 */
          #if __x86_64__
          #define __NR_statx 332
          #else
          #define __NR_statx 383
          #endif

          #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

          int main(int argc, char *argv[])

          int dirfd = AT_FDCWD;
          int flags = AT_SYMLINK_NOFOLLOW;
          unsigned int mask = STATX_ALL;
          struct statx stxbuf;
          long ret = 0;

          int opt = 0;

          while(( opt = getopt(argc, argv, "alfd")) != -1)

          switch(opt) = AT_STATX_FORCE_SYNC;
          break;
          case 'd':
          flags &= ~AT_STATX_SYNC_TYPE;
          flags


          if (optind >= argc)
          exit(EXIT_FAILURE);


          for (; optind < argc; optind++)
          memset(&stxbuf, 0xbf, sizeof(stxbuf));
          ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
          if( ret < 0)

          perror("statx");
          return EXIT_FAILURE;

          printf("%lld.%un", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);

          return EXIT_SUCCESS;



          Then:



          $ make birth
          $ ./birth ./birth.c
          1511793291.254337149
          $ ./birth ./birth.c | xargs -I date -d @
          Mon Nov 27 14:34:51 UTC 2017


          In theory this should make the creation time accessible on more filesystems than just the ext* ones (debugfs is a tool for ext2/3/4 filesystems, and unusable on others). It did work for an XFS system, but not for NTFS and exfat. I guess the FUSE filesystems for those didn't include the creation time.




          Now that glibc has support for the statx(2) system call, stat will follow soon and we'll be able to use the plain old stat command for this.






          share|improve this answer
































            3














            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: -


            and/or



            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



















            1














            For what it's worth I was feeling pedantic so wrote a bash wrapper around stat to silently support crtime using debugfs to fetch it from an underlying ext4 filesystem if available. I hope it's robust. Find it here:



            https://github.com/bernd-wechner/Linux-Tools/blob/master/xstat



            Note that a fix is ostensibly on the todo list for Linux as documented in that script. So this wrapper has a nominal lifespan only until that is done and is more an exercise in what's doable.






            share|improve this answer




















            • 1





              Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

              – Stéphane Chazelas
              Jun 3 '17 at 9:35






            • 1





              Awesome! Good news indeed.

              – Bernd Wechner
              Jun 3 '17 at 10:18






            • 5





              With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

              – Nick
              Sep 22 '17 at 9:53











            • "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

              – Bernd Wechner
              Aug 30 '18 at 7:09











            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f50177%2fbirth-is-empty-on-ext4%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            5 Answers
            5






            active

            oldest

            votes








            5 Answers
            5






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            81














            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
            398264


            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
            EXTENTS:
            (0):3308774


            1Linus' 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






            • 4





              @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











            • 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.

              – ctrl-alt-delor
              Aug 11 '14 at 11:27







            • 2





              Can this be used to get creation time of files from a network-mounted filesystem?

              – taranaki
              Sep 20 '18 at 18:32






            • 1





              So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

              – sinekonata
              Mar 1 at 3:10















            81














            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
            398264


            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
            EXTENTS:
            (0):3308774


            1Linus' 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






            • 4





              @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











            • 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.

              – ctrl-alt-delor
              Aug 11 '14 at 11:27







            • 2





              Can this be used to get creation time of files from a network-mounted filesystem?

              – taranaki
              Sep 20 '18 at 18:32






            • 1





              So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

              – sinekonata
              Mar 1 at 3:10













            81












            81








            81







            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
            398264


            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
            EXTENTS:
            (0):3308774


            1Linus' reply on LKML thread






            share|improve this answer















            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
            398264


            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
            EXTENTS:
            (0):3308774


            1Linus' reply on LKML thread







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 13 '17 at 12:37









            Community

            1




            1










            answered Oct 8 '12 at 5:04









            don_crisstidon_crissti

            52k15141169




            52k15141169












            • 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






            • 4





              @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











            • 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.

              – ctrl-alt-delor
              Aug 11 '14 at 11:27







            • 2





              Can this be used to get creation time of files from a network-mounted filesystem?

              – taranaki
              Sep 20 '18 at 18:32






            • 1





              So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

              – sinekonata
              Mar 1 at 3:10

















            • 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






            • 4





              @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











            • 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.

              – ctrl-alt-delor
              Aug 11 '14 at 11:27







            • 2





              Can this be used to get creation time of files from a network-mounted filesystem?

              – taranaki
              Sep 20 '18 at 18:32






            • 1





              So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

              – sinekonata
              Mar 1 at 3:10
















            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





            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




            4




            4





            @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





            @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













            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.

            – ctrl-alt-delor
            Aug 11 '14 at 11:27






            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.

            – ctrl-alt-delor
            Aug 11 '14 at 11:27





            2




            2





            Can this be used to get creation time of files from a network-mounted filesystem?

            – taranaki
            Sep 20 '18 at 18:32





            Can this be used to get creation time of files from a network-mounted filesystem?

            – taranaki
            Sep 20 '18 at 18:32




            1




            1





            So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

            – sinekonata
            Mar 1 at 3:10





            So this is not a time stamp that goes beyond the creation of the file system. It means that if a file was created 25 years ago and copied through lots of different physical or mounted systems, there is no way at all to find the information of the date of creation in any of the metadata? So the only way to know when a file was made is to type it into the file name? Or inside the content? Is there any reason for this seemingly odd non implementation?

            – sinekonata
            Mar 1 at 3:10













            27














            I combined this into a simple shell function:



            get_crtime() 
            grep -oP 'crtime.*--s*K.*')
            printf "%st%sn" "$target" "$crtime"
            done



            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






            • 1





              Thanks for having all the steps combined into one function.

              – WinEunuuchs2Unix
              Dec 23 '18 at 18:38















            27














            I combined this into a simple shell function:



            get_crtime() 
            grep -oP 'crtime.*--s*K.*')
            printf "%st%sn" "$target" "$crtime"
            done



            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






            • 1





              Thanks for having all the steps combined into one function.

              – WinEunuuchs2Unix
              Dec 23 '18 at 18:38













            27












            27








            27







            I combined this into a simple shell function:



            get_crtime() 
            grep -oP 'crtime.*--s*K.*')
            printf "%st%sn" "$target" "$crtime"
            done



            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















            I combined this into a simple shell function:



            get_crtime() 
            grep -oP 'crtime.*--s*K.*')
            printf "%st%sn" "$target" "$crtime"
            done



            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














            share|improve this answer



            share|improve this answer








            edited 17 hours ago









            dessert

            1,262724




            1,262724










            answered May 21 '14 at 15:37









            terdonterdon

            134k33270450




            134k33270450












            • 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






            • 1





              Thanks for having all the steps combined into one function.

              – WinEunuuchs2Unix
              Dec 23 '18 at 18:38

















            • 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






            • 1





              Thanks for having all the steps combined into one function.

              – WinEunuuchs2Unix
              Dec 23 '18 at 18:38
















            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





            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





            @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




            1




            1





            Thanks for having all the steps combined into one function.

            – WinEunuuchs2Unix
            Dec 23 '18 at 18:38





            Thanks for having all the steps combined into one function.

            – WinEunuuchs2Unix
            Dec 23 '18 at 18:38











            14














            The xstat function never got merged into mainline. However, a new statx call was proposed later on, and was merged in Linux 4.11. The new statx(2) system call does include a creation time in its return struct.



            However, userland has yet to catch up - it's not easy to call system calls directly in a C program. Typically glibc provides a wrapper that makes the job easy, but glibc added a wrapper for statx(2) only in 2.28 (release August 2018). Luckily, @whotwagner wrote a sample C program that shows how to use the statx(2) system call on x86 and x86-64 systems. Its output is the same format as stat's default, without any formatting options, but it's simple to modify it to print just the birth time. (If you have a new enough glibc, you won't need this - you can use statx directly as described in man 2 statx).



            First, clone it:



            git clone https://github.com/whotwagner/statx-fun


            You can compile the statx.c code, or, if you just want the birth time, create a birth.c in the cloned directory with the following code (which is a minimal version of statx.c printing just the creation timestamp including nanosecond precision):



            #define _GNU_SOURCE
            #define _ATFILE_SOURCE
            #include <stdio.h>
            #include <stdlib.h>
            #include <sys/types.h>
            #include <unistd.h>
            #include <fcntl.h>
            #include "statx.h"
            #include <time.h>
            #include <getopt.h>
            #include <string.h>

            // does not (yet) provide a wrapper for the statx() system call
            #include <sys/syscall.h>

            /* this code works ony with x86 and x86_64 */
            #if __x86_64__
            #define __NR_statx 332
            #else
            #define __NR_statx 383
            #endif

            #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

            int main(int argc, char *argv[])

            int dirfd = AT_FDCWD;
            int flags = AT_SYMLINK_NOFOLLOW;
            unsigned int mask = STATX_ALL;
            struct statx stxbuf;
            long ret = 0;

            int opt = 0;

            while(( opt = getopt(argc, argv, "alfd")) != -1)

            switch(opt) = AT_STATX_FORCE_SYNC;
            break;
            case 'd':
            flags &= ~AT_STATX_SYNC_TYPE;
            flags


            if (optind >= argc)
            exit(EXIT_FAILURE);


            for (; optind < argc; optind++)
            memset(&stxbuf, 0xbf, sizeof(stxbuf));
            ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
            if( ret < 0)

            perror("statx");
            return EXIT_FAILURE;

            printf("%lld.%un", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);

            return EXIT_SUCCESS;



            Then:



            $ make birth
            $ ./birth ./birth.c
            1511793291.254337149
            $ ./birth ./birth.c | xargs -I date -d @
            Mon Nov 27 14:34:51 UTC 2017


            In theory this should make the creation time accessible on more filesystems than just the ext* ones (debugfs is a tool for ext2/3/4 filesystems, and unusable on others). It did work for an XFS system, but not for NTFS and exfat. I guess the FUSE filesystems for those didn't include the creation time.




            Now that glibc has support for the statx(2) system call, stat will follow soon and we'll be able to use the plain old stat command for this.






            share|improve this answer





























              14














              The xstat function never got merged into mainline. However, a new statx call was proposed later on, and was merged in Linux 4.11. The new statx(2) system call does include a creation time in its return struct.



              However, userland has yet to catch up - it's not easy to call system calls directly in a C program. Typically glibc provides a wrapper that makes the job easy, but glibc added a wrapper for statx(2) only in 2.28 (release August 2018). Luckily, @whotwagner wrote a sample C program that shows how to use the statx(2) system call on x86 and x86-64 systems. Its output is the same format as stat's default, without any formatting options, but it's simple to modify it to print just the birth time. (If you have a new enough glibc, you won't need this - you can use statx directly as described in man 2 statx).



              First, clone it:



              git clone https://github.com/whotwagner/statx-fun


              You can compile the statx.c code, or, if you just want the birth time, create a birth.c in the cloned directory with the following code (which is a minimal version of statx.c printing just the creation timestamp including nanosecond precision):



              #define _GNU_SOURCE
              #define _ATFILE_SOURCE
              #include <stdio.h>
              #include <stdlib.h>
              #include <sys/types.h>
              #include <unistd.h>
              #include <fcntl.h>
              #include "statx.h"
              #include <time.h>
              #include <getopt.h>
              #include <string.h>

              // does not (yet) provide a wrapper for the statx() system call
              #include <sys/syscall.h>

              /* this code works ony with x86 and x86_64 */
              #if __x86_64__
              #define __NR_statx 332
              #else
              #define __NR_statx 383
              #endif

              #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

              int main(int argc, char *argv[])

              int dirfd = AT_FDCWD;
              int flags = AT_SYMLINK_NOFOLLOW;
              unsigned int mask = STATX_ALL;
              struct statx stxbuf;
              long ret = 0;

              int opt = 0;

              while(( opt = getopt(argc, argv, "alfd")) != -1)

              switch(opt) = AT_STATX_FORCE_SYNC;
              break;
              case 'd':
              flags &= ~AT_STATX_SYNC_TYPE;
              flags


              if (optind >= argc)
              exit(EXIT_FAILURE);


              for (; optind < argc; optind++)
              memset(&stxbuf, 0xbf, sizeof(stxbuf));
              ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
              if( ret < 0)

              perror("statx");
              return EXIT_FAILURE;

              printf("%lld.%un", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);

              return EXIT_SUCCESS;



              Then:



              $ make birth
              $ ./birth ./birth.c
              1511793291.254337149
              $ ./birth ./birth.c | xargs -I date -d @
              Mon Nov 27 14:34:51 UTC 2017


              In theory this should make the creation time accessible on more filesystems than just the ext* ones (debugfs is a tool for ext2/3/4 filesystems, and unusable on others). It did work for an XFS system, but not for NTFS and exfat. I guess the FUSE filesystems for those didn't include the creation time.




              Now that glibc has support for the statx(2) system call, stat will follow soon and we'll be able to use the plain old stat command for this.






              share|improve this answer



























                14












                14








                14







                The xstat function never got merged into mainline. However, a new statx call was proposed later on, and was merged in Linux 4.11. The new statx(2) system call does include a creation time in its return struct.



                However, userland has yet to catch up - it's not easy to call system calls directly in a C program. Typically glibc provides a wrapper that makes the job easy, but glibc added a wrapper for statx(2) only in 2.28 (release August 2018). Luckily, @whotwagner wrote a sample C program that shows how to use the statx(2) system call on x86 and x86-64 systems. Its output is the same format as stat's default, without any formatting options, but it's simple to modify it to print just the birth time. (If you have a new enough glibc, you won't need this - you can use statx directly as described in man 2 statx).



                First, clone it:



                git clone https://github.com/whotwagner/statx-fun


                You can compile the statx.c code, or, if you just want the birth time, create a birth.c in the cloned directory with the following code (which is a minimal version of statx.c printing just the creation timestamp including nanosecond precision):



                #define _GNU_SOURCE
                #define _ATFILE_SOURCE
                #include <stdio.h>
                #include <stdlib.h>
                #include <sys/types.h>
                #include <unistd.h>
                #include <fcntl.h>
                #include "statx.h"
                #include <time.h>
                #include <getopt.h>
                #include <string.h>

                // does not (yet) provide a wrapper for the statx() system call
                #include <sys/syscall.h>

                /* this code works ony with x86 and x86_64 */
                #if __x86_64__
                #define __NR_statx 332
                #else
                #define __NR_statx 383
                #endif

                #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

                int main(int argc, char *argv[])

                int dirfd = AT_FDCWD;
                int flags = AT_SYMLINK_NOFOLLOW;
                unsigned int mask = STATX_ALL;
                struct statx stxbuf;
                long ret = 0;

                int opt = 0;

                while(( opt = getopt(argc, argv, "alfd")) != -1)

                switch(opt) = AT_STATX_FORCE_SYNC;
                break;
                case 'd':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags


                if (optind >= argc)
                exit(EXIT_FAILURE);


                for (; optind < argc; optind++)
                memset(&stxbuf, 0xbf, sizeof(stxbuf));
                ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
                if( ret < 0)

                perror("statx");
                return EXIT_FAILURE;

                printf("%lld.%un", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);

                return EXIT_SUCCESS;



                Then:



                $ make birth
                $ ./birth ./birth.c
                1511793291.254337149
                $ ./birth ./birth.c | xargs -I date -d @
                Mon Nov 27 14:34:51 UTC 2017


                In theory this should make the creation time accessible on more filesystems than just the ext* ones (debugfs is a tool for ext2/3/4 filesystems, and unusable on others). It did work for an XFS system, but not for NTFS and exfat. I guess the FUSE filesystems for those didn't include the creation time.




                Now that glibc has support for the statx(2) system call, stat will follow soon and we'll be able to use the plain old stat command for this.






                share|improve this answer















                The xstat function never got merged into mainline. However, a new statx call was proposed later on, and was merged in Linux 4.11. The new statx(2) system call does include a creation time in its return struct.



                However, userland has yet to catch up - it's not easy to call system calls directly in a C program. Typically glibc provides a wrapper that makes the job easy, but glibc added a wrapper for statx(2) only in 2.28 (release August 2018). Luckily, @whotwagner wrote a sample C program that shows how to use the statx(2) system call on x86 and x86-64 systems. Its output is the same format as stat's default, without any formatting options, but it's simple to modify it to print just the birth time. (If you have a new enough glibc, you won't need this - you can use statx directly as described in man 2 statx).



                First, clone it:



                git clone https://github.com/whotwagner/statx-fun


                You can compile the statx.c code, or, if you just want the birth time, create a birth.c in the cloned directory with the following code (which is a minimal version of statx.c printing just the creation timestamp including nanosecond precision):



                #define _GNU_SOURCE
                #define _ATFILE_SOURCE
                #include <stdio.h>
                #include <stdlib.h>
                #include <sys/types.h>
                #include <unistd.h>
                #include <fcntl.h>
                #include "statx.h"
                #include <time.h>
                #include <getopt.h>
                #include <string.h>

                // does not (yet) provide a wrapper for the statx() system call
                #include <sys/syscall.h>

                /* this code works ony with x86 and x86_64 */
                #if __x86_64__
                #define __NR_statx 332
                #else
                #define __NR_statx 383
                #endif

                #define statx(a,b,c,d,e) syscall(__NR_statx,(a),(b),(c),(d),(e))

                int main(int argc, char *argv[])

                int dirfd = AT_FDCWD;
                int flags = AT_SYMLINK_NOFOLLOW;
                unsigned int mask = STATX_ALL;
                struct statx stxbuf;
                long ret = 0;

                int opt = 0;

                while(( opt = getopt(argc, argv, "alfd")) != -1)

                switch(opt) = AT_STATX_FORCE_SYNC;
                break;
                case 'd':
                flags &= ~AT_STATX_SYNC_TYPE;
                flags


                if (optind >= argc)
                exit(EXIT_FAILURE);


                for (; optind < argc; optind++)
                memset(&stxbuf, 0xbf, sizeof(stxbuf));
                ret = statx(dirfd, argv[optind], flags, mask, &stxbuf);
                if( ret < 0)

                perror("statx");
                return EXIT_FAILURE;

                printf("%lld.%un", *&stxbuf.stx_btime.tv_sec, *&stxbuf.stx_btime.tv_nsec);

                return EXIT_SUCCESS;



                Then:



                $ make birth
                $ ./birth ./birth.c
                1511793291.254337149
                $ ./birth ./birth.c | xargs -I date -d @
                Mon Nov 27 14:34:51 UTC 2017


                In theory this should make the creation time accessible on more filesystems than just the ext* ones (debugfs is a tool for ext2/3/4 filesystems, and unusable on others). It did work for an XFS system, but not for NTFS and exfat. I guess the FUSE filesystems for those didn't include the creation time.




                Now that glibc has support for the statx(2) system call, stat will follow soon and we'll be able to use the plain old stat command for this.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 20 '18 at 9:59

























                answered Nov 27 '17 at 15:24









                murumuru

                37.9k590166




                37.9k590166





















                    3














                    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: -


                    and/or



                    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
















                    3














                    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: -


                    and/or



                    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














                    3












                    3








                    3







                    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: -


                    and/or



                    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















                    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: -


                    and/or



                    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














                    share|improve this answer



                    share|improve this answer








                    edited Mar 28 '15 at 6:14

























                    answered Mar 27 '15 at 20:59









                    Franklin PiatFranklin Piat

                    1,9182028




                    1,9182028












                    • 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


















                    • 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

















                    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






                    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












                    1














                    For what it's worth I was feeling pedantic so wrote a bash wrapper around stat to silently support crtime using debugfs to fetch it from an underlying ext4 filesystem if available. I hope it's robust. Find it here:



                    https://github.com/bernd-wechner/Linux-Tools/blob/master/xstat



                    Note that a fix is ostensibly on the todo list for Linux as documented in that script. So this wrapper has a nominal lifespan only until that is done and is more an exercise in what's doable.






                    share|improve this answer




















                    • 1





                      Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                      – Stéphane Chazelas
                      Jun 3 '17 at 9:35






                    • 1





                      Awesome! Good news indeed.

                      – Bernd Wechner
                      Jun 3 '17 at 10:18






                    • 5





                      With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                      – Nick
                      Sep 22 '17 at 9:53











                    • "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                      – Bernd Wechner
                      Aug 30 '18 at 7:09















                    1














                    For what it's worth I was feeling pedantic so wrote a bash wrapper around stat to silently support crtime using debugfs to fetch it from an underlying ext4 filesystem if available. I hope it's robust. Find it here:



                    https://github.com/bernd-wechner/Linux-Tools/blob/master/xstat



                    Note that a fix is ostensibly on the todo list for Linux as documented in that script. So this wrapper has a nominal lifespan only until that is done and is more an exercise in what's doable.






                    share|improve this answer




















                    • 1





                      Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                      – Stéphane Chazelas
                      Jun 3 '17 at 9:35






                    • 1





                      Awesome! Good news indeed.

                      – Bernd Wechner
                      Jun 3 '17 at 10:18






                    • 5





                      With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                      – Nick
                      Sep 22 '17 at 9:53











                    • "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                      – Bernd Wechner
                      Aug 30 '18 at 7:09













                    1












                    1








                    1







                    For what it's worth I was feeling pedantic so wrote a bash wrapper around stat to silently support crtime using debugfs to fetch it from an underlying ext4 filesystem if available. I hope it's robust. Find it here:



                    https://github.com/bernd-wechner/Linux-Tools/blob/master/xstat



                    Note that a fix is ostensibly on the todo list for Linux as documented in that script. So this wrapper has a nominal lifespan only until that is done and is more an exercise in what's doable.






                    share|improve this answer















                    For what it's worth I was feeling pedantic so wrote a bash wrapper around stat to silently support crtime using debugfs to fetch it from an underlying ext4 filesystem if available. I hope it's robust. Find it here:



                    https://github.com/bernd-wechner/Linux-Tools/blob/master/xstat



                    Note that a fix is ostensibly on the todo list for Linux as documented in that script. So this wrapper has a nominal lifespan only until that is done and is more an exercise in what's doable.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jun 3 '17 at 10:18

























                    answered Jun 3 '17 at 9:31









                    Bernd WechnerBernd Wechner

                    1113




                    1113







                    • 1





                      Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                      – Stéphane Chazelas
                      Jun 3 '17 at 9:35






                    • 1





                      Awesome! Good news indeed.

                      – Bernd Wechner
                      Jun 3 '17 at 10:18






                    • 5





                      With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                      – Nick
                      Sep 22 '17 at 9:53











                    • "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                      – Bernd Wechner
                      Aug 30 '18 at 7:09












                    • 1





                      Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                      – Stéphane Chazelas
                      Jun 3 '17 at 9:35






                    • 1





                      Awesome! Good news indeed.

                      – Bernd Wechner
                      Jun 3 '17 at 10:18






                    • 5





                      With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                      – Nick
                      Sep 22 '17 at 9:53











                    • "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                      – Bernd Wechner
                      Aug 30 '18 at 7:09







                    1




                    1





                    Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                    – Stéphane Chazelas
                    Jun 3 '17 at 9:35





                    Note that xstat() has eventually been added to Linux, so it's only a matter of time before the GNU libc and find add support for it.

                    – Stéphane Chazelas
                    Jun 3 '17 at 9:35




                    1




                    1





                    Awesome! Good news indeed.

                    – Bernd Wechner
                    Jun 3 '17 at 10:18





                    Awesome! Good news indeed.

                    – Bernd Wechner
                    Jun 3 '17 at 10:18




                    5




                    5





                    With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                    – Nick
                    Sep 22 '17 at 9:53





                    With apologies for being pedantic, you seem not to understand the meaning of "pedantic".

                    – Nick
                    Sep 22 '17 at 9:53













                    "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                    – Bernd Wechner
                    Aug 30 '18 at 7:09





                    "overly concerned with minute details or formalisms" - as in, the accepted answer is fine, but ... let's formalise it. ;-)

                    – Bernd Wechner
                    Aug 30 '18 at 7:09

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f50177%2fbirth-is-empty-on-ext4%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    -ext4, filesystems, stat

                    Popular posts from this blog

                    Frič See also Navigation menuinternal link

                    Identify plant with long narrow paired leaves and reddish stems Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?What is this plant with long sharp leaves? Is it a weed?What is this 3ft high, stalky plant, with mid sized narrow leaves?What is this young shrub with opposite ovate, crenate leaves and reddish stems?What is this plant with large broad serrated leaves?Identify this upright branching weed with long leaves and reddish stemsPlease help me identify this bulbous plant with long, broad leaves and white flowersWhat is this small annual with narrow gray/green leaves and rust colored daisy-type flowers?What is this chilli plant?Does anyone know what type of chilli plant this is?Help identify this plant

                    fontconfig warning: “/etc/fonts/fonts.conf”, line 100: unknown “element blank” The 2019 Stack Overflow Developer Survey Results Are In“tar: unrecognized option --warning” during 'apt-get install'How to fix Fontconfig errorHow do I figure out which font file is chosen for a system generic font alias?Why are some apt-get-installed fonts being ignored by fc-list, xfontsel, etc?Reload settings in /etc/fonts/conf.dTaking 30 seconds longer to boot after upgrade from jessie to stretchHow to match multiple font names with a single <match> element?Adding a custom font to fontconfigRemoving fonts from fontconfig <match> resultsBroken fonts after upgrading Firefox ESR to latest Firefox