找回密码
 立即注册
首页 业界区 安全 Win32基于Refs实现 Copy On Write

Win32基于Refs实现 Copy On Write

雌鲳签 5 天前
Refs相对Ntfs来说,有一个很重要的技术 Block Clone。
块克隆指令文件系统代表应用程序复制一段文件字节,目标文件可能与源文件相同,也可能不同。不幸的是,传统的复制操作成本高昂,因为它们会触发对底层物理数据的昂贵读写操作。
然而,在ReFS中,块克隆执行的是低成本元数据操作,而不是读取和写入文件数据。因为ReFS允许多个文件共享相同的逻辑簇(卷上的物理位置),复制操作只需将文件的一个区域重新映射到单独的物理位置,将昂贵的物理操作转换为快速的逻辑操作。这使得复制操作能够更快完成,并且对底层存储的I/O操作更少。这项改进也惠及了虚拟化工作负载,因为在使用块克隆操作时,.vhdx检查点合并操作的速度显著提升。此外,由于多个文件可以共享相同的逻辑簇,相同的数据不会多次物理存储,从而提高了存储容量。
根据MS DOCS所述,Block Clone允许多个文件共享一个物理区块,减少文件复制时候占用额外的资源。因此我们可以借助这个技术来实现类似BtrFS的COW(Copy On Write)技术。
FILE_SUPPORTS_BLOCK_REFCOUNTING 可以判断文件是否支持Block Clone。
参考代码:https://github.com/0xbadfca11/reflink/blob/master/reflink.cpp
实现代码
[code]#include #include #include #include #include constexpr LONG64 inline ROUNDUP(LONG64 file_size, ULONG cluster_size) noexcept{        return (file_size + cluster_size - 1) / cluster_size * cluster_size;}BOOL CreateForkW(HANDLE hSrc, HANDLE hDst){        DWORD fs_flags;        if (!GetVolumeInformationByHandleW(hSrc, NULL, 0, NULL, NULL, &fs_flags, NULL, 0))        {                return FALSE;        }        if (!(fs_flags & FILE_SUPPORTS_BLOCK_REFCOUNTING))        {                SetLastError(ERROR_NOT_CAPABLE);                return FALSE;        }        FILE_END_OF_FILE_INFO file_size;        if (!GetFileSizeEx(hSrc, &file_size.EndOfFile))        {                return FALSE;        }        FILE_BASIC_INFO file_basic;        if (!GetFileInformationByHandleEx(hSrc, FileBasicInfo, &file_basic, sizeof file_basic))         {                return FALSE;        }        DWORD _;        FSCTL_GET_INTEGRITY_INFORMATION_BUFFER get_integrity;        if (!DeviceIoControl(hSrc, FSCTL_GET_INTEGRITY_INFORMATION, nullptr, 0, &get_integrity, sizeof get_integrity, &_, nullptr))        {                return FALSE;        }        FILE_DISPOSITION_INFO dispos = { TRUE };        if (!SetFileInformationByHandle(hDst, FileDispositionInfo, &dispos, sizeof dispos))        {                return FALSE;        }        if (!DeviceIoControl(hDst, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &_, NULL))        {                return FALSE;        }        FSCTL_SET_INTEGRITY_INFORMATION_BUFFER set_integrity = { get_integrity.ChecksumAlgorithm, get_integrity.Reserved, get_integrity.Flags };        if (!DeviceIoControl(hDst, FSCTL_SET_INTEGRITY_INFORMATION, &set_integrity, sizeof set_integrity, nullptr, 0, nullptr, nullptr))        {                return FALSE;        }        if (!SetFileInformationByHandle(hDst, FileEndOfFileInfo, &file_size, sizeof file_size))        {                return FALSE;        }        const LONG64 split_threshold = (1LL  0; offset += split_threshold, remain -= split_threshold)        {                dup_extent.SourceFileOffset.QuadPart = dup_extent.TargetFileOffset.QuadPart = offset;                dup_extent.ByteCount.QuadPart = min(split_threshold, remain);                _ASSERTE(dup_extent.SourceFileOffset.QuadPart % get_integrity.ClusterSizeInBytes == 0);                _ASSERTE(dup_extent.ByteCount.QuadPart % get_integrity.ClusterSizeInBytes == 0);                _ASSERTE(dup_extent.ByteCount.QuadPart
您需要登录后才可以回帖 登录 | 立即注册