SSD 驱动器上的分区/dev/sda3
不包含任何文件系统,但包含垃圾。如何对整个分区执行 TRIM/DISCARD 操作?
答案1
如果你的 util-linux 版本足够新(2012 年 9 月),实际上有一个专门构建的工具,blkdiscard
,这是实现此目的的最佳方法:
sudo blkdiscard /dev/sda3
但是如果您需要与旧版 Linux 发行版兼容,请继续阅读...有些情况下hdparm
/wiper.sh
会拒绝触碰卷,因为它不是分区,所以我们需要一些超越它的东西。
我发现最受支持的方法是利用 Linux 交换卷在启用时支持 DISCARD 的事实。末尾的 wipefs 在那里,因此稍后卷不会被识别为交换。
D=/dev/sda3 ; mkswap $D && swapon -d $D && swapoff $D && wipefs -o 0xff6 $D
这会在大多数设备上发出 DISCARD 指令。
答案2
我知道这个问题很老了,但是......
这最簡單实现此目的的方法是在分区上创建一个 ext4 文件系统,并使用较新版本的mkfs.ext4
。此工具所做的第一件事是修剪整个分区。完成此操作后,您可以使用所需的任何文件系统覆盖其创建的数据。
(例如,我刚刚这样做了,在 SD 卡上创建一个新的 vfat 分区。)
答案3
hdparm --trim-sector-ranges 是低级的,它应该直接与 SSD 对话,因此不依赖于文件系统。wiper.sh 所做的是使用文件系统特定的程序将空闲(文件系统)区域映射到(硬件)SSD 扇区,然后使用 hdparm 修剪这些扇区。
回答这个问题,你可以使用 hdparm 来修剪该分区,但你应该非常小心。方法是获取分区使用的扇区范围,然后对该扇区范围使用 hdparm。您可能需要传递多个扇区范围,因为 --trim-sector-ranges 的每个范围最多可以有 65535 个扇区。
fdisk -l 可以告诉您分区的起始位置和大小。请注意 fdisk 使用的单元以及 SSD 的扇区大小。
示例(我的 SSD):
Device Boot Start End Blocks Id System
/dev/sdb1 2048 39070079 19534016 83 Linux
要丢弃此分区之前的空间,我可以从扇区 1 开始修剪 2047 个扇区(在我的 SSD 上为 512 字节大小):。hdparm --trim-sector-ranges 1:2047
我无法从扇区 0 开始修剪,因为那是 MBR(不知道 GPT 是怎么回事)。
要丢弃分区使用的空间,我会这样做hdparm --trim-sector-ranges 2048:65535 67583:65535 133118:65535 ...
。它可以编写脚本,但我现在不打算编写脚本。
另外只是为了确保:我不能保证任何事情,我可能计算了错误的扇区,在有效使用--trim-sector-ranges之前请对所有内容进行备份。
笔记:如果您像我所展示的那样修剪了第一个分区之前的“空白”空间,请务必在重新启动之前重新安装 GRUB(或您使用的任何引导加载程序),因为 GRUB 将其部分存储在第一个分区之前的“未使用”扇区中。不知道其他引导加载程序,但我猜可能是这种情况,所以要小心。
答案4
blkdiscard
可以对分区进行操作,而不仅仅是对整个驱动器进行操作。我在 Fedora 20 上成功测试了它。我检查了源代码blkdiscard
- 这是一个非常简单的程序,对分区一无所知。我假设内核会进行翻译。
要非常小心,blkdiscard
不要问任何问题,也不要显示任何进度信息。
如果 blkdiscard 不可用,请使用此脚本并将其输出提供给 hdparm。第一个参数是要修剪的扇区数,第二个参数是要修剪的第一个扇区。
#! /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