Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support file block copy on write on Windows #86681

Open
danmoseley opened this issue May 24, 2023 · 22 comments
Open

support file block copy on write on Windows #86681

danmoseley opened this issue May 24, 2023 · 22 comments
Assignees
Labels
area-System.IO tenet-performance Performance related issue
Milestone

Comments

@danmoseley
Copy link
Member

On ReFS, Windows supports a block copy operation, like copy on write but at a sub-file level.

https://learn.microsoft.com/en-us/windows/win32/fileio/block-cloning
https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-fsctl_duplicate_extents_to_file

This has existed for several years, but is suddenly more interesting now because of the announcement of dev drive.

We should enlighten File.Copy to use this on Windows when possible, so that MSBuild, Nuget etc work extra fast on dev drive.

@ghost ghost added the untriaged New issue has not been triaged by the area owner label May 24, 2023
@ghost
Copy link

ghost commented May 24, 2023

Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.

Issue Details

On ReFS, Windows supports a block copy operation, like copy on write but at a sub-file level.

https://learn.microsoft.com/en-us/windows/win32/fileio/block-cloning
https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-fsctl_duplicate_extents_to_file

This has existed for several years, but is suddenly more interesting now because of the announcement of dev drive.

We should enlighten File.Copy to use this on Windows when possible, so that MSBuild, Nuget etc work extra fast on dev drive.

Author: danmoseley
Assignees: -
Labels:

area-System.IO

Milestone: -

@danmoseley
Copy link
Member Author

@hamarb123 if you comment on this issue, I'll be able to assign it to you.

@hamarb123
Copy link
Contributor

Comment :)

@danmoseley
Copy link
Member Author

cc @rainersigwald this should speed up MSBuild if it isn't already doing hardlinks.
cc @aortiz-msft this should help Nuget, but only where it's doing File.Copy or equivalent -- it looks like you do FileStream copy in some places which wouldn't benefit .. we might want to take a look at that at some point to see whether it's necessary.

@adamsitnik adamsitnik added tenet-performance Performance related issue and removed untriaged New issue has not been triaged by the area owner labels May 24, 2023
@adamsitnik adamsitnik added this to the 8.0.0 milestone May 24, 2023
@rainersigwald
Copy link
Member

MSBuild has an option to do hardlinks (the Copy task's UseHardlinksIfPossible parameter, exposed in common targets as $(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)) but you have to be very careful with them since modifying (what looks like) a file in your output can silently corrupt your NuGet cache or other files, so they're not widely used.

@danmoseley
Copy link
Member Author

@jkoritzinsky
Copy link
Member

There's a Copy On Write MSBuild SDK that utilizes the ReFS CloneFile API for a custom implementation of the Copy MSBuild task. Might be useful.

@danmoseley
Copy link
Member Author

Yep, I think @hamarb123 is going to crib from that (https://github.com/microsoft/CopyOnWrite)

@hamarb123
Copy link
Contributor

hamarb123 commented Jun 21, 2023

I have been delayed in making a PR for this due to BSODs caused by my code/Windows, which were hard to track down. I've now found the root cause, and documented it at: microsoft/CopyOnWrite#24. Hopefully I can make a PR with a workaround soon.

@danmoseley
Copy link
Member Author

@hamarb123 how's it looking - I see they're fixing the BSOD (nice find)

@hamarb123
Copy link
Contributor

hamarb123 commented Jun 27, 2023

@danmoseley I've been working on some other projects this last week, I plan to have a go at getting a working PR ready tomorrow - assuming there's no other issues like this one, it should be do-able. Thanks

@danmoseley
Copy link
Member Author

@hamarb123 Sounds good - I actually didn't intend to hurry you.. was just curious

@danmoseley
Copy link
Member Author

danmoseley commented Jul 11, 2023

@hamarb123 actually I'm now starting to have my eye on platform shutdown date for .NET 8. I believe this repo is about to stop feature work, but historically have allowed community contributions at all times into main, occasionally holding risky commits until after branching. Do you expect to have a PR soon? If not that's totally fine but I may ask around to see whether there's someone who can look nearer term.

@hamarb123
Copy link
Contributor

@danmoseley sorry, it slipped my mind. I have mostly functional code, will make a PR after confirming the code still currently works locally.

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 11, 2023
@jozkee jozkee modified the milestones: 8.0.0, 9.0.0 Jul 28, 2023
@ghost ghost added in-pr There is an active PR which will close this issue when it is merged and removed in-pr There is an active PR which will close this issue when it is merged labels Sep 25, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Oct 26, 2023
@huoyaoyuan
Copy link
Member

ReFS filesystem Block Cloning Support is now available in the Windows copy engine.
(https://blogs.windows.com/windows-insider/2023/10/25/announcing-windows-11-insider-preview-build-25982-canary-channel/)

What does this mean for, copy action in explorer (likely not), or the CopyFile syscall?
Do we still need explicit support in .NET?

@hamarb123
Copy link
Contributor

@erikmav do you know? ^

@huoyaoyuan
Copy link
Member

so this feature adds native support to copy actions and APIs on Windows.

It sounds like a new syscall available?

@erikmav
Copy link

erikmav commented Oct 26, 2023

Not a new syscall, the Windows team liked the CoW approach and numbers from the .NET approach (https://aka.ms/EngMSDevDrive) and I've been working with them to turn it on by default in the CopyFile(Ex) API calls. Unless something goes wrong between now and release of this Canary feature to cause the code to change, on Dev Drive (and ReFS) copying a file will just clone instead.

I'm partway through perf testing the canary bits on internal repos with and without the .NET package turned on. Keep an eye on the Eng@MS blog for more info as soon as next week.

@erikmav
Copy link

erikmav commented Oct 26, 2023

Assuming the feature makes it to the February release without semantic changes, it would resolve this issue. Better to wait to resolve this until it's known that clone is on by default in the final release.

@erikmav
Copy link

erikmav commented Nov 7, 2023

FYI latest in blog series (encapsulates what's already here): https://devblogs.microsoft.com/engineering-at-microsoft/copy-on-write-in-win32-api-early-access/

@adamsitnik adamsitnik modified the milestones: 9.0.0, 10.0.0 Jul 18, 2024
@huoyaoyuan
Copy link
Member

I updated my machine to 24H2 recently, and the plain copy command seems to be CoW cloning on regular ReFS drive (not Dev Drive). Doing it in the syscall itself would probably have better performance.

Do we still need this functionality? It will only benefit a limited set of configurations, and not required for "the future".

@hamarb123
Copy link
Contributor

hamarb123 commented Oct 8, 2024

No, I don't think so - I assumed the conclusion was that we will just benefit from OS support when available, and not worry about the other cases, since they're rare anyway.

If it's still wanted, I could have a go at implementing it some time, but I had just assumed it wasn't needed anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.IO tenet-performance Performance related issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants