I was wondering whether mounting an SSD using the discard option (documented in man mount) is actually required for ATA TRIM to be sent to the SSD's controller.

The evidence is a bit circumstantial: Whether or not I mount a partition with discard on a SanDisk SSD PLUS, deleted files can't be restored by running TestDisk moments after the deletion. File paths are intact, but file content is gone. From this I suspect that TRIM ran on the SSD and made the file contents irrecoverable.

Looking at systemctl list-timers, there doesn't seem to be a unit that runs fstrim.

Does the kernel send TRIM after file deletion although the partition is not mounted with discard? Or is it another reason why TestDisk reliably can't restore files from the SSD?

I'm on Arch Linux 5.12.3.

findmnt tells me this about the partitions and their mount options:

TARGET                       SOURCE     FSTYPE OPTIONS
/                            /dev/sda3  ext4   rw,relatime
└─/sda1                      /dev/sda1  ext4   rw,relatime,lazytime,discard

If the filesystem is mounted with discard, then deleting files will automatically cause the TRIM command to be issued. This often has a negative performance impact, so it's generally better not to use that mount option and to instead run fstrim periodically, which will work as long as all the block device layers support it (for example, if you're using LUKS for encryption, you'll need to use cryptsetup --allow-discards). Unless you use this mount option, the TRIM command will not be automatically sent by the filesystem driver when you unlink files.

You could also try mounting with nodiscard. Although this is the default and usually unnecessary, it is possible that your filesystem had continuous TRIM support added to its default options set through tune2fs -o discard /dev/sda1. You can remove it with tune2fs -o ^discard /dev/sda1.

You might be able to find out what the issue is by using the debugfs utility to first list the actual blocks within a file before you delete it, and then directly access those blocks after deletion to see if they have been zeroed or return undisturbed but unallocated data.

Here's a shell script to test whether debugfs can read the contents of a deleted file using its block number:


echo "Current date: $(date)" > "$file"; sync
# Get the device of our test file, for example "/dev/sda1"
device=$(df -P "$file" | awk 'END{print $1}')
# The block of the file's contents, stat gets the inode number
block=$(sudo debugfs -R "blocks <$(stat -c %i "$file")>" "$device")
rm $file; sync
# Read the contents of the deleted file, -D bypasses the buffer cache
sudo debugfs -D -R "block_dump $block" "$device"
  • 1
    Thanks for your help! I've added a script to your answer that demonstrated that debugfs can indeed read the contents of a deleted file from the SSD if the file system is not mounted using discard and I don't run fstrim after the deletion. The opposite is true as well: debugfs reads zeros from the blocks of the deleted file if the file system is mounted using discard or I run fstrim after deletion. This also indicates that the DRAT word of my SSD is zeros. – Matthias Braun Jun 8 at 10:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.