blkdiscard apparently failing to fully discard a SATA SSD

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello!

When I use blkdiscard to trim a SATA SSD in its entirety, it seems that
not all sectors are getting trimmed.  I initially ran into this on a
Sandisk SDSSDA240G, but I reproduced it on a Samsung 850 EVO M.2 250GB
and a few other SATA SSDs.  This happens on Fedora kernel
"4.11.11-300.fc26.x86_64" and a few other Fedora kernels.

For this test, I have the following SSD:

	[root@testbox ~]# smartctl -a /dev/sda
	smartctl 6.5 2016-05-07 r4318 [x86_64-linux-4.11.11-300.fc26.x86_64] (local build)
	Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org

	=== START OF INFORMATION SECTION ===
	Model Family:     SandForce Driven SSDs
	Device Model:     SanDisk SDSSDA240G
	Serial Number:    154307402302
	LU WWN Device Id: 5 001b44 ef905163e
	Firmware Version: Z22000RL
	User Capacity:    240,057,409,536 bytes [240 GB]
	[...]

Which at the start of the test is completely "empty":

	[root@testbox ~]# cat /dev/sda | od -t x1 -Ax -
	000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	37e4896000
	[root@testbox ~]#

I then write a 64 bit byte offset from the start of the disk to every
64 bit word, which looks as follows:

	[root@testbox ~]# cat /dev/sda | od -Ax -t x1 - | head -5
	000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08
	000010 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 18
	000020 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 28
	000030 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 38
	000040 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 48
	[root@testbox ~]# cat /dev/sda | od -Ax -t x1 - | head -1048576 | tail -5
	ffffb0 00 00 00 00 00 ff ff b0 00 00 00 00 00 ff ff b8
	ffffc0 00 00 00 00 00 ff ff c0 00 00 00 00 00 ff ff c8
	ffffd0 00 00 00 00 00 ff ff d0 00 00 00 00 00 ff ff d8
	ffffe0 00 00 00 00 00 ff ff e0 00 00 00 00 00 ff ff e8
	fffff0 00 00 00 00 00 ff ff f0 00 00 00 00 00 ff ff f8
	[root@testbox ~]#

I then blkdiscard the whole SSD in one go:

	[root@testbox ~]# blkdiscard -v /dev/sda
	/dev/sda: Discarded 240057409536 bytes from the offset 0
	[root@testbox ~]#

>From summing iostat kB_wrtn column data during the blkdiscard, it seems
that all of the sectors on the SSD should have been covered by the trim
operation, but this doesn't seem to zero all of the sectors -- some of
them keep their original contents:

	[root@testbox ~]# cat /dev/sda | od -Ax -t x1 - | head -10
	000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	1fff000 00 00 00 00 01 ff f0 00 00 00 00 00 01 ff f0 08
	1fff010 00 00 00 00 01 ff f0 10 00 00 00 00 01 ff f0 18
	1fff020 00 00 00 00 01 ff f0 20 00 00 00 00 01 ff f0 28
	1fff030 00 00 00 00 01 ff f0 30 00 00 00 00 01 ff f0 38
	1fff040 00 00 00 00 01 ff f0 40 00 00 00 00 01 ff f0 48
	1fff050 00 00 00 00 01 ff f0 50 00 00 00 00 01 ff f0 58
	1fff060 00 00 00 00 01 ff f0 60 00 00 00 00 01 ff f0 68
	1fff070 00 00 00 00 01 ff f0 70 00 00 00 00 01 ff f0 78
	[...]

More specifically, there's this pattern:

	[root@testbox ~]# cat /dev/sda | od -Ax -t x1 - | grep -A1 -B2 '^*' | head -20
	000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	1fff000 00 00 00 00 01 ff f0 00 00 00 00 00 01 ff f0 08
	--
	1fffff0 00 00 00 00 01 ff ff f0 00 00 00 00 01 ff ff f8
	2000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	3fff000 00 00 00 00 03 ff f0 00 00 00 00 00 03 ff f0 08
	--
	3fffff0 00 00 00 00 03 ff ff f0 00 00 00 00 03 ff ff f8
	4000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	5fff000 00 00 00 00 05 ff f0 00 00 00 00 00 05 ff f0 08
	--
	5fffff0 00 00 00 00 05 ff ff f0 00 00 00 00 05 ff ff f8
	6000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	7fff000 00 00 00 00 07 ff f0 00 00 00 00 00 07 ff f0 08
	--
	7fffff0 00 00 00 00 07 ff ff f0 00 00 00 00 07 ff ff f8
	[...]

Even if trimming a sector doesn't guarantee that subsequent reads will
return zeroes, the weird thing is is that this behavior seems to be
consistent across different SSD models, down to which specific sectors
are zeroed and which are not.

If I blkdiscard the whole SSD again, the same pattern remains on the
disk, but if I blkdiscard it again with an appropriate offset:

	[root@testbox ~]# blkdiscard -v -o 1048576 /dev/sda
	/dev/sda: Discarded 240056360960 bytes from the offset 1048576
	[root@testbox ~]#

I then get an SSD that returns zeroes again from every sector:

	[root@testbox ~]# cat /dev/sda | od -t x1 -Ax -
	000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	*
	37e4896000
	[root@testbox ~]#

Since the pattern seems to be a consistent untrimmed 4096 bytes every
32 MiB, I wonder if there is maybe some off-by-one in discard request
processing somewhere.

Can anyone other than me reproduce this?


Cheers,
Lennert



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux