Over the years, Wine prefixes have gotten bigger and bigger, for a number of reasons. Creating a new Wine prefix for each application is still the current recommendation, as despite the best efforts of Wine developers, some applications still require system-wide workarounds. This leads to significant bloat for each application installed. With a MinGW build of Wine without Mono or Gecko, new 32-bit prefixes are over 150 MB, and new 64-bit prefixes are over 300 MB. The vast majority of these files are byte-for-byte identical to Wine's central DLL copies.
This patch set implements reflink support in Wine via the copy_file_range syscall. The reasons for selecting copy_file_range over FICLONE are outlined in patch 2. A previous unpublished version of this patch set used FICLONERANGE, but it was less convenient to use from setupapi and has inferior system support.
When reflink is supported by the underlying filesystem, new Wine prefix sizes with Mono and Gecko disabled are reduced to less than 1 MB. The resulting Wine prefix is byte-for-byte identical to one created without reflink, but occupies less space on disk. If hard links or symlinks were used, if an application such as winetricks writes to a system file, it would overwrite the central copy. With reflink, the file blocks will be transparently copied by the Linux kernel so that each Wine prefix can be independent.
Some files cannot be deduplicated in the current Wine system, as they are dynamically generated during the Wine prefix installation process. These include 16-bit fake DLLs and manifest files. In theory, it should be possible to pre-generate these files, but considering the Wine prefix size is already reduced to less than 1 MB, the extra space savings are likely not worth the effort.
Alex Xu (Hello71) (5): ntdll: add support for IOCTL_COPYCHUNK. kernelbase: use IOCTL_COPYCHUNK in CopyFile* setupapi: Use IOCTL_COPYCHUNK, avoid buffering whole file lmshare.h: define STYPE_TEMPORARY kernel32/tests: add IOCTL_COPYCHUNK test
configure | 1 + configure.ac | 1 + dlls/kernel32/tests/file.c | 137 +++++++++++++++++++++++++ dlls/kernelbase/file.c | 44 ++++---- dlls/ntdll/unix/file.c | 121 ++++++++++++++++++++++ dlls/setupapi/fakedll.c | 202 ++++++++++++++++++++----------------- include/config.h.in | 3 + include/lmshare.h | 11 +- include/winioctl.h | 34 +++++++ 9 files changed, 431 insertions(+), 123 deletions(-)