48

My partition /dev/sda3 on an SSD drive doesn't contain any filesystem, but it contains garbage. How do I do a TRIM/DISCARD operation on the whole partition?

4
  • 8
    I think the point is that he doesn't want to write any data, he wants the SSD to ERASE the flash block but leave it empty so it's available to be written to, known as freshing an SSD drive. Jul 8, 2011 at 20:44
  • 1
    ATA Secure Erase wiki ata.wiki.kernel.org/index.php/ATA_Secure_Erase
    – joe
    Jul 7, 2012 at 22:46
  • 1
    @joe: Your ATA Secure Erase link doesn't even mention parititions. I don't want to erase the entire drive, just a partition. And I don't want to risk accidentally erasing the whole drive.
    – pts
    Jul 10, 2012 at 15:03
  • 13
    @Doc: Filling the partition with garbage data is quite the opposite of pts' intention: It will tell the SSD that the partition is completely filled an in use. This will decrease performance and life-time of the SSD.
    – Black
    Jul 28, 2012 at 6:51

7 Answers 7

62

If your version of util-linux is new enough (September 2012), there is actually a purpose-built tool, blkdiscard, that is the best way to do this:

sudo blkdiscard /dev/sda3

But if you need compatibility to older Linux distro versions, read on... There are cases where hdparm/wiper.sh refuse to touch a volume because it's not a partition, so we need something beyond that.

The most supported way I've found is to take advantage of the fact that Linux swap volumes support DISCARD when they are enabled. The wipefs on the end is there so the volume isn't recognized as swap later.

D=/dev/sda3 ; mkswap $D && swapon -d $D && swapoff $D && wipefs -o 0xff6 $D

This issues the DISCARD on the majority of the device.

4
  • 4
    Thanks, didn't know about blkdiscard. Dangerous command... :) Sep 28, 2013 at 20:43
  • 2
    Why? I just looked it in up in the manual: WARNING: All data in the discarded region on the device will be lost!
    – MrCalvin
    May 30, 2019 at 8:01
  • 1
    Does this ensure that the SSD will erase all written pages (so they can be written again immediately)?
    – iBug
    Dec 7, 2020 at 18:27
  • 4
    @iBug that depends on the SSD's firmware. All pages related to the discarded ranges can definitely be written again immediately, but if you try to read them immediately after trim (before a write), the exact result may vary depending on SSD firmware (zeros, deterministic, random data)
    – robbat2
    Dec 16, 2020 at 5:52
11

I know this question is pretty old, but...

The simplest way to do this is to simply create an ext4 filesystem on the partition with a reasonably recent version of mkfs.ext4. The first thing this tool does is TRIM the entire partition. Once you've done that, you can overwrite the data it's created with whatever filesystem you desire.

(I've just done this to create a new vfat partition on an SD card, for example.)

4
  • Thank you for the tip! FYI After TRIMming, writes some blocks with metadata for an empty ext4 filesystem, so the a few percent of the partition remains unTRIMmed.
    – pts
    Jan 11, 2013 at 19:47
  • 8
    @pts You can minimize the size of the metadata by reducing the journal size and number of inodes: mkfs.ext4 -J size=4 -N1 /dev/my/device Jan 9, 2015 at 12:23
  • 6
    @AryehLeibTaurog Using -E lazy_journal_init appears to result in slightly less writes than -J size=4 does. (Based on experiments using a sparse file rather than a physical SSD and du to verify how much had been written.)
    – kasperd
    Oct 18, 2015 at 12:27
  • @kasperd A clever experiment with interesting results! Thanks. Oct 18, 2015 at 19:48
9

hdparm --trim-sector-ranges is low level, it is supposed to talk directly to the SSD, so no dependency on the filesystem. What wiper.sh does is use filesystem specific programs to map free (filesystem) regions to (hardware) SSD sectors, them use hdparm to trim those.

Answering the question, you can use hdparm to trim that partition, but you should be very careful. The way to do it is obtaining the sector range used by the partition, then use hdparm on that sector range. Probably you'll need to pass multiple sector ranges, as each range for --trim-sector-ranges can have at maximum 65535 sectors.

fdisk -l can tell you the beginning and size of the partitions. Pay attention to the units in use by fdisk, and to the sector size of your SSD.

Example (my SSD):

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            2048    39070079    19534016   83  Linux

To discard the space before this partition, I could trim 2047 (512 byte sized, on my SSD) sectors starting from sector 1: hdparm --trim-sector-ranges 1:2047. I can't trim starting from sector 0 because that is the MBR (dunno how it goes for GPT).

To discard the space used by the partition, I'd do hdparm --trim-sector-ranges 2048:65535 67583:65535 133118:65535 .... It can be scripted but I'm not going to write one now.

Also just to be sure: I'm not guaranteeing anything here, I may have miscalculated sectors, do a backup of everything before effectively using --trim-sector-ranges.

Note: if you trim the "empty" space before the first partition, like I showed, be sure to reinstall GRUB (or whatever boot loader you use) before rebooting, as GRUB stores part of it on "unused" sectors before the first partition. Don't know other bootloaders but I guess it may be the case, so take care.

1
  • 8
    wiper.sh is obsoleted by fstrim which is much safer, but for this specific usage blkdiscard beats both. In 2013, there is no need to risk computing ranges manually.
    – Gabriel
    Sep 19, 2013 at 18:54
8

You could have a look at the script wiper.sh included with the hdparm package. It uses the hdparm command --trim-sector-ranges to TRIM all empty sectors on a partition, at least if it contains an ext3/4 filesystem. Not sure if it works with unformatted partitions, but you could always temporarily format it with ext4.

2
  • Formatting it with ext4 and then running wiper.sh would trim almost all of the partition except for the ext4 metadata. But I'd like to trim the whole partition.
    – pts
    Jul 13, 2011 at 22:24
  • 2
    @pts: I suggest you look at the code of wiper.sh and try to figure out how it deduces the trim ranges. Then you could manually send a trim range to hdparm to TRIM the whole partition. Jul 14, 2011 at 8:40
5

blkdiscard can work on partitions, not just on whole drives. I tested it successfully on Fedora 20. I checked the sources of blkdiscard - it's a very simple program that knows nothing about partitions. I assume the kernel does the translation.

Be very careful, blkdiscard asks no questions and shows no progress information.

If blkdiscard is not available, use this script and feed its output to hdparm. First argument is the number of sectors to trim, the second is the first sector to trim.

#! /bin/sh
# List ranges for hdparm --trim-sector-ranges-stdin
: ${MAXSECT=65535}
test $# = 2 || { echo "Usage: trimlist sectors offset" >&2; exit 1; }
sectors=$1
pos=$2
while test $sectors -gt 0; do
    if test $sectors -gt $MAXSECT; then
            size=$MAXSECT
    else
            size=$sectors
    fi
    echo $pos:$size
    sectors=$(($sectors-$size))
    pos=$(($pos+$size))
done
1

For some reason on recent Ubuntu and Debian blkdiscard stopped accepting partitions as parameters, but only full device. I was using it previously thus was surprised and looking for other options.

I like proski answer but concept of calculating sector ranges is very unfriendly for me, thus I rewrote the script to provide start sector and end sector as parameters, to feed to hdparm trim command.

This approach allows simply read the output of fdisk -l for start and end positions, calculating simple as that just -1 for end sector if we take start sector of following partition or just +1 for start if we want to trim free space after last data partition.

Important note: I have noticed that trimming till the end of drive will corrupt second GPT copy, thus will require fdisk and write again for fix.

And of cause please make backup if you have any important data on drive you want to trim.

Here is my modified version of a script gen_trim.sh:

#!/bin/bash
# List ranges for hdparm --trim-sector-ranges-stdin
MAXSECT=65535
test $# = 2 || { echo "Usage: $0 offset last_sector" >&2; exit 1; }
pos=$1
lsector=$2
sectors=$(($lsector-$pos))

while [ $pos -lt $lsector ] ; do

    if [ $sectors -gt $MAXSECT ] ; then
            size=$MAXSECT
    else
            size=$sectors
    fi

    echo $pos:$size
    sectors=$(($sectors-$size))
    pos=$(($pos+$size))

done

Usage:

./gen_trim.sh start_sector end_sector | hdparm --please-destroy-my-drive --trim-sector-ranges-stdin /dev/sdX

example, I want to trim end of drive, free space after last partition:

fdisk -l /dev/sdb
Disk /dev/sdb: 1.86 TiB, 2048408248320 bytes, 4000797360 sectors
...
/dev/sdb4  209717248 3907029134 3697311887  1.7T Linux LVM

last partition sector=3907029134 thus start sector is 3907029135

and end sector is simply drive size in sectors: 4000797360

then script is:

./gen_trim.sh 3907029135 4000797360 | hdparm --please-destroy-my-drive --trim-sector-ranges-stdin /dev/sdX

where sdX is my ssd or nvme drive.

1
  • I tried it with a partition on Linux Mint 21.2, and it worked.
    – Alexey
    Jul 24 at 10:46
-1

Here's an interesting article that talks about using HDDErase to invoke the SSD's built-in secure erase feature, which should get you want you want:

http://www.windowsitpro.com/article/file-systems/q-how-can-i-reset-a-solid-state-disk-ssd-to-a-fully-erased-clean-state-

2
  • Thank you for your answer, but it doesn't work, since 1) it erases the whole drive 2) it requires Microsoft Windows, and I was looking for a Linux solution.
    – pts
    Jul 13, 2011 at 22:23
  • 4
    Note also that this is basically the same that blkdiscard --secure does.
    – ntninja
    May 18, 2018 at 11:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .