Trim在SCSI 里面的同等命令叫做UNMAP,NVMe里面叫Deallocate,文件系统叫做discard。
在SSD存储系统中,定期主动执行trim指令,能够减少因IO触发的写放大,从而提升IO性能。另外,主动trim后,再次读取返回0,这样使client无法读取已经删除的数据,有利于数据安全(隐私),特别是在公有云中,存储系统主动trim是很有必要的。以下是原理解释和代码验证。
NVMe接收到Deallocate Command后,会标记这些数据块,再次读这些数据块对应的LBA 时返回0。
Zeroout ioctl 通过__blkdev_issue_zeroout发送写0命令,在block层,拆分成128KB blocksize,要求偏移量和长度512B对齐。
NVMe:The NVM Express command set has a generic Dataset Management command, for hinting the host's intent to the storage device on a set of block ranges. One of its operations, deallocate performs trim. It also has a Write Zeroes command that provides a deallocate hint and allows the disk to trim and return zeroes.
参考:https://en.wikipedia.org/wiki/Trim_(computing)
代码验证:
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BLKDISCARD _IO(0x12,119)
#define OFFSET (0)
#define BUF_SIZE (512<<10)
static int trim_test(int fd, uint64_t start, uint64_t len)
{
uint64_t r[2];
r[0] = start;
r[1] = len;
return ioctl(fd, BLKDISCARD, &r);
}
int main()
{
int fd;
char* dev_name = "/dev/nvme";
void* buf = NULL;
fd = open(dev_name, O_RDWR | O_DIRECT);
if (fd < 0)
{
perror("Failed to open device");
return errno;
}
buf = memalign(4096,BUF_SIZE);
memset(buf, 0, BUF_SIZE);
strcpy(buf,"ssd trim test");
strcpy(buf + BUF_SIZE - 4096,"ssd trim test");
int len = pwrite(fd, buf, BUF_SIZE, OFFSET);
if (len < 0)
{
perror("write device failed");
return errno;
}
memset(buf, 0, BUF_SIZE);
len = pread(fd, buf, 4096, OFFSET);
printf("before trim:%s\n", (char*)buf);
memset(buf, 0, BUF_SIZE);
len = pread(fd, buf, 4096, OFFSET+BUF_SIZE-4096);
printf("without trim:%s\n", (char*)buf);
if (trim_test(fd,OFFSET,4096) < 0)
{
perror("failed to trim");
return errno;
}
memset(buf, 0, BUF_SIZE);
len = pread(fd, buf, 4096, OFFSET);
printf("after trim:%s\n", (char*)buf);
memset(buf, 0, BUF_SIZE);
len = pread(fd, buf, 4096, OFFSET+BUF_SIZE-4096);
printf("without trim:%s\n", (char*)buf);
return 0;
}
结果在trim之后数据消失,说明能够保护数据安全,也提供了另外一种删除数据的方法:
before trim:ssd trim test
without trim:ssd trim test
after trim:
without trim:ssd trim test
https://blog.csdn.net/WEI_GW2012/article/details/80327778