Copying or restoring crtime for files/directories on ext4fs filesystem

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.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x