用于修剪驱动器上未分配空间的实用程序

Jas*_*n C 12 partition sd-card trim

我有一个带有几个 ext4 分区的驱动器(SD 卡),但还有一些未分配的空间。该fstrim实用程序只能在文件系统中工作。在我重新发明轮子并编写一个之前,是否有另一种实用程序可以修剪未分配的空间(或者可以修剪明确指定的范围)?

我可以验证控制器当前知道设备上的大部分未分配空间是否可用,正如我观察到的那样,在这张特定的卡上,读取到修剪过的空间返回 0,但设备的扫描显示留下了大量的垃圾数据。

编辑:我在使用hdparm. 下面的示例丢弃了第一个扇区,但无论我指定的范围如何,我都会看到相同的结果。fstrim设备上没有问题:

root@ubuntu:~# hdparm --please-destroy-my-drive --trim-sector-ranges 0:1 --verbose /dev/mmcblk0 

/dev/mmcblk0:
trimming 1 sectors from 1 ranges
outgoing cdb:  85 0d 06 00 01 00 01 00 00 00 00 00 00 40 06 00
outgoing_data:  
00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

ioctl(fd,SG_IO): Invalid argument
FAILED: Invalid argument
Run Code Online (Sandbox Code Playgroud)

我正在进一步调查,但有人有任何见解吗?

fro*_*utz 20

如果您有足够新版本的util-linux,它包含blkdiscard能够修剪整个设备或使用--offset--length选项的设备范围内的工具。

请注意: blkdiscard是危险的,如果你让它修剪错误的区域,你的数据就会消失!

因此,您可以找出分区表的未分区(空闲)区域,然后使用此工具修剪它们。对于msdosgpt分区,parted提供像这样的空闲区域:

# parted -m /dev/sda unit b print free | grep ':free;'
1:17408B:1048575B:1031168B:free;
1:64022904832B:64023240191B:335360B:free;
Run Code Online (Sandbox Code Playgroud)

给它添加一个循环...

while IFS=: read -ra FREE
do
    echo blkdiscard --offset ${FREE[1]%%B} --length ${FREE[3]%%B} /dev/sda
done < <(parted -m /dev/sda unit b print free | grep ':free;')
Run Code Online (Sandbox Code Playgroud)

哪个打印

blkdiscard --offset 17408 --length 1031168 /dev/sda
blkdiscard --offset 64022904832 --length 335360 /dev/sda
Run Code Online (Sandbox Code Playgroud)

验证这个输出对你来说是正确的,如果你喜欢添加额外的选项(详细?),最后删除echo它以便实际执行,你应该被设置。

该示例的第二个命令实际上失败了,因为长度太小 - 在循环内部可能值得检查,忽略小于 1MB 的区域,因为它们不太可能被成功修剪。


如果您使用 LVM 而不是分区,您可以为未占用的空间创建一个 LV 并修剪:

lvcreate -l100%FREE -n blkdiscard SSD-VG
blkdiscard -v /dev/SSD-VG/blkdiscard
lvremove SSD-VG/blkdiscard
Run Code Online (Sandbox Code Playgroud)

如果您issue_discards = 1在 中设置lvm.conf,则可以跳过blkdiscard调用,因为 LVM 将lvremove自行发出 TRIM 。


Mic*_*ann 7

hdparm --trim-sector-ranges可以修剪一个范围。手册页警告使用它,所以你最好确保你有正确的范围和语法。

我认为为分区外的所有数据发送修剪会很危险,因为那里有时会存在一些隐藏数据,例如引导加载程序代码或第二个分区表。您需要知道确切,分区之外的哪些区域真正未使用。