From 7db82ede943f9a75651ebabc80207d4efc79ce05 Mon Sep 17 00:00:00 2001 From: extratype Date: Sun, 5 Dec 2021 15:27:03 +0900 Subject: [PATCH] Release 1.2 --- README.md | 40 +++++++++++++++++++++++++++++++--------- chunkdisk.rc | 8 ++++---- docs/changes.txt | 7 +++++++ main.cpp | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 963d25f..6e35e34 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,16 @@ Mount a disk image split over files (*chunks*) in multiple directories (*parts*). -## Getting Started +## Features + +* Unnecessary chunks become empty (0 bytes) after TRIM. +* Unused files are closed to save system resources and update timestamps when the disk is idle or under low load. +* Supports differential disks. -I'm not responsible for the data stored using chunkdisk! +## Getting Started 1. Install [WinSpd](https://github.com/billziss-gh/winspd/releases/tag/v1.0B1). -2. Copy chunkdisk-x64.exe and winspd-x64.dll to C:\Program Files (x86)\WinSpd\bin\. +2. Copy chunkdisk-x64.exe and winspd-x64.dll (See [issues](#issues)) to C:\Program Files (x86)\WinSpd\bin\. 3. Merge install.reg. 4. Create a `.chunkdisk` file. For example: @@ -23,11 +27,14 @@ I'm not responsible for the data stored using chunkdisk! 7. Run `diskmgmt.msc` to open Disk Management, [initialize the disk](https://docs.microsoft.com/en-us/windows-server/storage/disk-management/initialize-new-disks) and [create a partition](https://support.microsoft.com/en-us/windows/create-and-format-a-hard-disk-partition-bbb8e185-1bda-ecd1-3465-c9728f7d7d2e). 8. To dismount, right-click the drive in File Explorer and choose "Eject". -## WARNINGS +## Caution + +⚠️Be careful not to modify data when the disk is mounted, the authors are not responsible for your data! + +* The `.chunkdisk` file is read once. It can be modified and even deleted by other applications. +* Don't modify, add, remove and move around chunk files. They are not write-protected even when being used by chunkdisk. Changes outside chunkdisk may not be visible to the virtual disk, cause I/O errors or even corrupt the file system. -* MAKE A BACKUP of `.chunkdisk` file. Chunkdisk reads it only once when it's mounted. It can be read, modified and even deleted by others while the disk is mounted. -* DO NOT add, remove and move around chunk files when the disk is mounted. Doing so confuses chunkdisk and causes I/O errors. -* DO NOT directly modify chunk files. They are NOT write-protected even when being used. +chunkdisk places a `.lock` file to every part directory to prevent mounting the same disk twice, which will be removed upon exit. If `-W 0` option (mount as read-only) is given you have to remove it on your own to mount the disk again with `-W 1` option. ## `.chunkdisk` File Specs @@ -35,7 +42,6 @@ I'm not responsible for the data stored using chunkdisk! {disk size in bytes} {chunk file size in bytes} {max. number of chunks} {absolute path to a directory} -{max. number of chunks} {absolute path to a directory} ... ``` @@ -46,7 +52,7 @@ I'm not responsible for the data stored using chunkdisk! ## Issues * winspd-x64.dll is not compatible with the original to workaround [an issue](https://github.com/billziss-gh/winspd/issues/10). Specifically, invoking `SpdStorageUnitSendResponse()` or `SpdIoctlTransact()` leads to an undefined behavior. It's fine with the current WinSpd binaries though. The source code is available [here](https://github.com/extratype/winspd). -* Random I/O performance is not great with SSDs. +* Random I/O performance is not great with NVMe SSDs. ## Notes and Tips @@ -59,3 +65,19 @@ I'm not responsible for the data stored using chunkdisk! * When a file in the virtual disk gets deleted the corresponding chunk file may become empty if it is larger than the chunk size. This is done via SCSI UNMAP command (a.k.a. TRIM) requested by Windows. * You can identify the file in disk for specific chunk or identify the chunk used by specific file. Use `fsutil volume querycluster` for the former, `fsutil file queryextents` for the latter. Use `diskpart` to know the partition offset. For NTFS volumes the cluster size is typically 4096 and LCN 0 corresponds to offset from 0 (inclusive) to 4096 (exclusive) of the partition. + +## Differential disk + +`.chunkdisk` file specs for differential disks: + +```plaintext +{absolute path to the parent disk} +{disk size in bytes} +{chunk file size in bytes} +{max. number of chunks} {absolute path to a directory} +... +``` + +The parent disk can be either non-differential or differential. The disk size and chunk file size should be equal for all involving `.chunkdisk`. Every part directory should be unique. Parent disks are mounted as read-only (as if `-W 0` option is given). Disks mounted as read-only can be shared over multiple running instances. + +You may discard or *merge* the differential disk. To merge, first make sure the differential disk and its parent are not mounted. Then remove `.lock` files in all parts of the parent disk (to mount it later with `-W 1` option); move and overwite all chunk files to the parent disk. The other differential disks based on it should be discarded. diff --git a/chunkdisk.rc b/chunkdisk.rc index 178bf35..289909d 100644 --- a/chunkdisk.rc +++ b/chunkdisk.rc @@ -1,8 +1,8 @@ #include VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 + FILEVERSION 1,2,0,0 + PRODUCTVERSION 1,2,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -18,12 +18,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "chunkdisk" - VALUE "FileVersion", "1.0.0.0" + VALUE "FileVersion", "1.2.0.0" VALUE "InternalName", "chunkdisk.exe" VALUE "LegalCopyright", "Copyright (C) 2021 extratype" VALUE "OriginalFilename", "chunkdisk.exe" VALUE "ProductName", "chunkdisk" - VALUE "ProductVersion", "1.0.0.0" + VALUE "ProductVersion", "1.2.0.0" END END BLOCK "VarFileInfo" diff --git a/docs/changes.txt b/docs/changes.txt index b00f731..d12dbf8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -42,3 +42,10 @@ v1.0 * Improve handling buffers for small-sized I/O's. * Fix bugs in unaligned (page-based) I/O's. * Fix inactivity timer. + +v1.2 + +* New feature: differential disk. +* The `.lock` file is not removed automatically on exit if `-W 0` option is given. Manually remove it to mount again with `-W 1` option. +* Close file handles to trigger updating metadata when the virtual disk is not only idle but under low load for a minute. +* Handle the case where the file system does not support FSCTL_SET_ZERO_DATA IOCTL. diff --git a/main.cpp b/main.cpp index f39a956..34709b0 100644 --- a/main.cpp +++ b/main.cpp @@ -442,7 +442,7 @@ DWORD CreateStorageUnit(PWSTR chunkdisk_file, const BOOLEAN write_protected, PWS err = [&bases, write_protected, pipe_name, &unit]() -> DWORD { constexpr wchar_t ProductId[] = L"ChunkDisk"; - constexpr wchar_t ProductRevision[] = L"1.0"; + constexpr wchar_t ProductRevision[] = L"1.2"; auto unit_params = SPD_STORAGE_UNIT_PARAMS(); UuidCreate(&unit_params.Guid);