Fake ext4 file creation dates for a large number of files by setting the system time

Recently, I downloaded a large number of photos from a cloud service to my local machine (Ubuntu 23.10). As is expected, the creation/birth date of those files was set to the actual download date. Now, after uploading the photos to a new cloud provider I noticed that my photos are sorted by creation date only (no support for image metadata apparently), which is, of course, pretty useless.

So far, so bad, it certainly isn’t a problem of Ubuntu. However, the first (and presumably simplest) solution that came to my mind is to change the files’ creation dates according to the respective metadata. Unfortunately, it turns out that changing a files creation date on Linux is not easily done. I don’t understand all the details, but it seems to have something to do with the creation date being maintained by the filesystem itself and not usually being exposed to the user. Note: While changing the modification date was no problem using the touch command, it did not solve my problem.

Long story short: The only solution that seems to work is the following:

  1. Read the metadata timestamp from the image, e.g. exiftool -T -DateTimeOriginal <file>
  2. Use timedatectl set-time to adjust the system time
  3. Copy the image file and delete the old one

I’ve tried it for individual files and it seems to work flawlessly. However, I’m a bit concerned with actually trying it for a significant number of files automatically. Are there any problems (with performance, precision or otherwise) I should be aware of?

EDIT: After @FedKad’s comment I noticed that the files are, in fact, sorted by upload date, not the file creation date. I apologize for not noticing before. Still, I’m going to keep the question, because I believe it is a problem others may find interesting (without the context).

Asked By: junjios

||

touch -t YYYYMMDDHHMM.SS filename should set timestamp for filename without changing system time.

See man touch for full description of touch command.

Answered By: Soren A

First of all, pCloud does support the modification date of the file. These are some files that I uploaded today to my pCloud account. I tested with the "pCloud drive" software (ver. 1.14.5) for Linux and also from the Web Interface using Firefox (https://my.pcloud.com/). The Linux touch -t works perfectly even on already uploaded files:

enter image description here

However, it seems that dates before the epoch are not supported.


Now the real part of your question:

How can I set the birth date of a file in an Ubuntu system to the time I want?

I never recommend changing system time for any purpose at all!

You can use the debugfs tool from the e2fsprogs package to change a specific file’s creation (=birth) date and time. Since this tool can be dangerous and would need to un-mount the file system containing your files, I would recommend creating a test filesystem:

$ cd /tmp
$ truncate --size 100m test100m
$ mkfs.ext4 test100m
mke2fs 1.47.0 (5-Feb-2023)
[...]
Writing superblocks and filesystem accounting information: done

$ mkdir /tmp/tmount
$ sudo mount /tmp/test100m /tmp/tmount

$ cd /tmp/tmount
$ sudo mkdir testdir
$ sudo chown myuser:myuser testdir

$ cd testdir
$ touch testfile
$ stat testfile
  File: testfile
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 7,21    Inode: 13          Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/   myuser)   Gid: ( 1000/   myuser)
Access: 2024-06-02 16:09:44.095324795 +0300
Modify: 2024-06-02 16:09:44.095324795 +0300
Change: 2024-06-02 16:09:44.095324795 +0300
 Birth: 2024-06-02 16:09:44.095324795 +0300

$ touch -t 193811100905 testfile 
$ stat testfile
  File: testfile
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 7,21    Inode: 13          Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/   myuser)   Gid: ( 1000/   myuser)
Access: 1938-11-10 09:05:00.000000000 +0200
Modify: 1938-11-10 09:05:00.000000000 +0200
Change: 2024-06-02 16:12:28.703865067 +0300
 Birth: 2024-06-02 16:09:44.095324795 +0300

Note that only the access and modification times have changed!

Now remount the file system with debugfs:

$ sudo umount /tmp/tmount

$ sudo debugfs -w /tmp/test100m
debugfs 1.47.0 (5-Feb-2023)
debugfs:  cd testdir
debugfs:  stat testfile

Inode: 13   Type: regular    Mode:  0664   Flags: 0x80000
Generation: 3688309895    Version: 0x00000000:00000005
User:  1000   Group:  1000   Project:     0   Size: 0
File ACL: 0
Links: 1   Blockcount: 0
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x665c6fbc:a7d083ac -- Sun Jun  2 16:12:28 2024
 atime: 0xc56c0d1c:00000000 -- Thu Nov 10 09:05:00 1938
 mtime: 0xc56c0d1c:00000000 -- Thu Nov 10 09:05:00 1938
crtime: 0x665c6f18:16ba29ec -- Sun Jun  2 16:09:44 2024
Size of extra inode fields: 32
Inode checksum: 0x2b0c4f97
EXTENTS:
(END)

debugfs:  set_inode_field <13> crtime 192310292030
debugfs:  quit

$ sudo mount /tmp/test100m /tmp/tmount
$ cd /tmp/tmount/testdir
$ stat testfile
  File: testfile
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 7,21    Inode: 13          Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/   myuser)   Gid: ( 1000/   myuser)
Access: 1938-11-10 09:05:00.000000000 +0200
Modify: 1938-11-10 09:05:00.000000000 +0200
Change: 2024-06-02 16:12:28.703865067 +0300
 Birth: 1923-10-30 22:30:00.004807757 +0200

The set_inode_field command of debugfs can change the birth date and time which is stored in the inode of the file. The inode number (<13> in the above example) was obtained from the first line of the stat command above. The date specified here in debugfs is in UTC.

Answered By: FedKad
Categories: Answers Tags: , , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.