Your logic is not incorrect. But it is only valid if some conditions are satisfied.
The TRIM command, as specified in the ATA command set, may or may not zero the sectors it is issued against.
Actually, the standard focuses on what data has to be returned after TRIM has been issued1:
The follow behaviors are specified by this standard for sectors that the device trims (see 184.108.40.206):
a) non-deterministic - the data in response to a read from a trimmed sector may change for each read until the sector is written by the host;
b) Deterministic Read After Trim (DRAT) - the data returned in response to a read of a trimmed sector does not change, but may be different than the data that was previously returned; and
c) Read Zeroes After Trim (RZAT) - the data returned in response to a read of the trimmed sector is zero.
[...] For both DRAT and non-deterministic storage devices, the data returned in response to a read command to an LBA that has been successfully trimmed:
a) may be the previously returned data for the specified LBA;
b) may be a pattern generated by the storage device; and
c) is not data previously written to a different LBA by the host.
Thus, what your device returns after
fstrim depends on the features it implements. Unless it supports RZAT, the assumption that data read from a trimmed device will be only zeros does not hold.
You can use
hdparm to check for this:
sudo hdparm -I /dev/sdX | grep -i trim
I performed some tests using two SSDs,
sdb. Same manufacturer, different models, with different ATA conformance:
$ sudo hdparm -i /dev/sdb
Drive conforms to: Unspecified: ATA/ATAPI-3,4,5,6,7
$ sudo hdparm -i /dev/sda
Drive conforms to: unknown: ATA/ATAPI-2,3,4,5,6,7
The two SSDs have different support for TRIM:
$ sudo hdparm -I /dev/sda | grep -i trim
* Data Set Management TRIM supported (limit 1 block)
$ sudo hdparm -I /dev/sdb | grep -i trim
* Data Set Management TRIM supported (limit 8 blocks)
* Deterministic read ZEROs after TRIM
I can confirm that, after issuing
fstrim, the drive supporting "Deterministic read ZEROs after TRIM" (RZAT) seems to have actually zeroed the concerned partition almost entirely. Conversely, the other drive seems to have zeroed (or otherwise replaced with some highly compressible pattern) only a minor part of the freed space.
1 Online source: INCITS 529: Information technology - ATA/ATAPI Command Set - 4 (ACS-4)
Note on testing:
As pointed out by frostschutz in comments, a read after
fstrim may return data from the operating system cache, and not from the trimmed device. It is, for instance, what happened in this qustion.
(I would also point to this answer to the same question for an alternative method for testing TRIM).
fstrim and a subsequent read you may need to drop the cache, e.g. with:
echo 3 | sudo tee /proc/sys/vm/drop_caches
Depending on the size of the partition you are playing with, not dropping the cache may be enough for your tests to fail.
Note on your setup:
discard mount option enables continuous TRIM, i.e. any time files are deleted. It is not required by
fstrim. Indeed, on-demand TRIM and continuous TRIM are two distinct ways to menage TRIM operations. For further information I would point to Solid state drive on the Arch Linux Wiki, which has a detailed coverage of this matter.