2

I wonder if there are ways to copy or restore crtime (creation time) for inodes/files/directories in Linux in 2020. I've accidentally deleted a folder while I still have a full disk backup, but neither cp -a, nor rsync can restore/copy files/directories crtimes.

I have found a way to achieve it using debugfs but it's super complicated and I need to automate it (I have hundreds of deleted files/directories).

For the source disk you do this:

# debugfs /dev/sdXX
# stat /path
Inode: 432772   Type: directory    Mode:  0700   Flags: 0x80000
Generation: 3810862225    Version: 0x00000000:00000006
User:  1000   Group:  1000   Project:     0   Size: 4096
File ACL: 0
Links: 5   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5db96479:184bb16c -- Wed Oct 30 15:22:49 2019
 atime: 0x5b687c70:ee4dff18 -- Mon Aug  6 21:50:56 2018
 mtime: 0x5db96479:184bb16c -- Wed Oct 30 15:22:49 2019
crtime: 0x5b687c70:d35d1348 -- Mon Aug  6 21:50:56 2018
Size of extra inode fields: 32
Extended attributes:
  security.selinux (40)
EXTENTS:
(0):1737229

Remember the crtime, these are two fields, crtime_lo (yes, the first) and crtime_hi (the second)

Then for the destination disk you do this:

# debugfs -w /dev/sdYY
# set_inode_field /path crtime_lo 0x${1st_value_from_earlier}
# set_inode_field /path crtime_hi 0x${2nd_value_from_earlier}

Maybe there's something else I'm missing in the debugfs manual which could help me do that, so I'd be glad if people could help.

-f cmd_file surely seems like a nice way to start but still a little bit too difficult for me.

3 Answers3

6

I've actually solved it on my own. You never know what you can do till you try :-)

It must be safe to run even when all the filesystems are mounted read-write.

#! /bin/bash

dsk_src=/dev/sdc4 # source disk with original timestamps
mnt_src=/mnt/sdc4 # source disk mounted at this path
dsk_dst=/dev/sda4 # destination disk
directory=user/.thunderbird # the leading slash _must_ be omitted

cd $mnt_src || exit 1

find $directory -depth | while read name; do
    read crtime_lo crtime_hi < <(debugfs -R "stat \"/$name\"" $dsk_src 2>/dev/null | awk '/crtime:/{print $2}' | sed 's/0x//;s/:/ /')

    echo "File: $name"
    echo "crtime_lo: $crtime_lo"
    echo "crtime_hi: $crtime_hi"

    debugfs -w $dsk_dst -R "set_inode_field \"/$name\" crtime_lo 0x$crtime_lo"
    debugfs -w $dsk_dst -R "set_inode_field \"/$name\" crtime_hi 0x$crtime_hi"
done

If people are interested I can adjust the script to allow to use it within one partition as well, e.g. after running cp -a. It's quite easy actually.

  • This works if you copy a disk and it does not look nice. It does not work when restoring a backup. – schily Jun 07 '20 at 17:30
  • 1
    Note that using debugfs -w is not safe to use on a mounted filesystem. This is modifying the blocks of the filesystem beneath the kernel, and can result in filesystem corruption (e.g. overwriting other inodes in the same block that may have been modified by the kernel). On the read side, you can use statx() with kernels > 3.10 (IIRC) to read the stx_btime (birth time) field, but there is no kernel interface for storing the crtime/btime on a live filesystem, nor are the ext4 maintainers interested to add one. – LustreOne Jun 08 '20 at 23:42
  • 1
    Using debugfs as shown above is OK for an unmounted filesystem, but using separate debugfs commands can become very inefficient as the filesystem grows large and reading all of the metadata takes a long time. Instead, to make the above more efficient, you can generate just the list of commands, like "echo set_inode_field $name crtime_lo 0x$crtime_lo" and then pipe the whole while loop into "debugfs -w -f /dev/stdin $dsk_dst" so that it runs all of the commands in a single invocation. You could also dump the commands to a file first, to review them before execution. – LustreOne Jun 08 '20 at 23:45
  • 1
    I haven't checked the kernel code but altering crtime on a mounted filesystem shouldn't be be an issue because you're editing existing inodes internal attributes (not deleting or creating them) which must be safe. I've also confirmed that applying them to over two hundred files haven't caused any issues as a e2fsck run was clean. Piping debugfs commands surely looks like a nice idea but I just needed a quick hack and it worked perfectly. – Artem S. Tashkinov Jun 09 '20 at 13:47
1

If you have a modern tar archive that includes all time stamps, you can do this with star -xp -ctime ... in case you call star as root.

Note that this leẗ́s star cause time storms and should not be done in a serious multi user mode.

See http://schilytools.sourceforge.net/man/man1/star.1.html for moreinformation.

schily
  • 19,173
  • It does it through the arse though. From the manual: If star is run as root and if -ctime is used with the extract command and the same archive formats, this causes star to try to restore even the ctime of a file by generating time storms. – Artem S. Tashkinov Jun 07 '20 at 15:56
  • Well, this is the only fs and OS independent method to do that job and it works with a backup.... – schily Jun 07 '20 at 17:28
  • I agree however it only does the job with a relatively low precision. The script I wrote for Linux restores crtime with nanosecond precision. – Artem S. Tashkinov Jun 07 '20 at 18:53
  • The precision is better than microseconds if your OS is halfway decent. Note that this is 30 year old code and at that time many OS did not yet give better file time stamp resolution than seconds. – schily Jun 07 '20 at 20:47
  • 1
    @schily Perhaps it's a good time to add a Linux-specific code path to restore ctime to star! – FUZxxl Jun 12 '20 at 12:09
  • @FUZxxl is there such an interface? From the OP, there seems to be just a debug program (that seems to be a bad idea on a buzy filesystem), but no programming interface. – schily Jun 12 '20 at 12:48
  • @schily Good question! I'll try to find out. – FUZxxl Jun 12 '20 at 18:11
  • @FUZxxl Have you found out anything? – Artem S. Tashkinov Dec 13 '20 at 09:31
  • @ArtemS.Tashkinov Nope. – FUZxxl Dec 13 '20 at 11:16
0

In Windows, We use https://github.com/matt-wu/Ext3Fsd mount ext4 partition. Then the ext partition is mounted on the windows system just like the local partition and accesses normally as with NTFS,

At this time, we can use some software under windows, such as: rsync, SyncToy, UrBackup and other software that can retain the file creation time in windows, we synchronize the ntfs file to EXT4, Compare their creation time, and then mount it to the deeping Linux system in ext4, compare their creation time, which has been kept synchronized.

Windows can keep the creation time with github matt-wu/Ext3Fsd, but Linux can't.

mygit
  • 1
  • ext2fsd remains experimental, can cause data loss/fs corruption and it doesn't support modern ext4 features and requires Windows to be installed. There's a newer version albeit it's unsigned and requires disabling secure boot and driver signature verification: https://github.com/bobranten/Ext4Fsd – Artem S. Tashkinov Nov 30 '23 at 12:17
  • It does not support enabling 64-bit ext4, just turn it off. So far, the Linux kernel has not added an interface to modify the creation time, only an access interface But this is currently the only quick solution found to keep ext4 migrations and backups created (NTFS>ext4, Windows> Linux) – mygit Nov 30 '23 at 13:27