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.
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 usestatx()
with kernels > 3.10 (IIRC) to read thestx_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:42echo 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