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

Use copy_file_range(2) to implement System.Native.CopyFile() #33159

Closed
wants to merge 10 commits into from

Conversation

filipnavara
Copy link
Member

@filipnavara filipnavara commented Mar 4, 2020

Revival of #1495 and fix for #31429.

This cleans up the file locking code in PAL and the code paths introduced in dotnet/corefx#39235 to support clonefile API on macOS. Additionally, it introduces support for the copy_file_range API on newer Linux systems:

   The  copy_file_range()  system  call performs an in-kernel
   copy between two file descriptors without the addi‐ tional
   cost of transferring data from the kernel to user space and
   then back into the kernel.

   (...)

   copy_file_range()  gives  filesystems  an opportunity to
   implement "copy acceleration" techniques, such as the use of
   reflinks (i.e., two or more inodes that share pointers to the
   same copy-on-write disk blocks) or server-side-copy (in the
   case of NFS).

@filipnavara
Copy link
Member Author

Damn, should have been draft PR.

@filipnavara filipnavara changed the title CI test: Use copy_file_range(2) to implement System.Native.CopyFile() WIP: Use copy_file_range(2) to implement System.Native.CopyFile() Mar 4, 2020
@filipnavara
Copy link
Member Author

@lpereira I cannot test the Linux part locally at the moment but it seems that at least the macOS part works correctly now, including the new test. The last CI failure is infrastructure issue that would likely go away on re-trigger.

@lpereira
Copy link
Contributor

lpereira commented Mar 4, 2020

Thanks for looking a this, @filipnavara!

@carlossanlop carlossanlop marked this pull request as draft April 16, 2020 21:15
@carlossanlop
Copy link
Member

@filipnavara I converted it back to draft.

@filipnavara
Copy link
Member Author

@carlossanlop Yeah, it is basically done but we need to figure out whether @lpereira's PR will be the master one or this one.

@carlossanlop
Copy link
Member

I suggest we use @lpereira 's PR as the main one since it has most of the comment history, and we should close this one.

@filipnavara
Copy link
Member Author

filipnavara commented Apr 16, 2020

@carlossanlop Fine with me, but this one is based on top of it and adds more fixes to pass all the tests. I cannot edit someone else's PRs. The fixes are essential to get this in.

@carlossanlop
Copy link
Member

@lpereira if you're still going to work on this, can you please make sure to apply Filip's changes in your PR?

@carlossanlop
Copy link
Member

@filipnavara let's make this PR the main one. @lpereira may not be able to continue working on this issue since he moved to another team.

@filipnavara
Copy link
Member Author

I will update the description.

@filipnavara filipnavara changed the title WIP: Use copy_file_range(2) to implement System.Native.CopyFile() Use copy_file_range(2) to implement System.Native.CopyFile() Apr 23, 2020
lpereira and others added 10 commits April 23, 2020 23:38
This is in preparation to introduce a different method of copying files
on Linux, using the copy_file_range(2) system call.
From the man page:

       The  copy_file_range()  system  call performs an in-kernel
       copy between two file descriptors without the addi‐ tional
       cost of transferring data from the kernel to user space and
       then back into the kernel.

       (...)

       copy_file_range()  gives  filesystems  an opportunity to
       implement "copy acceleration" techniques, such as the use of
       reflinks (i.e., two or more inodes that share pointers to the
       same copy-on-write disk blocks) or server-side-copy (in the
       case of NFS).
There's already code to handle the existence of O_CLOEXEC in the
system, among other things, so just call the function to clean things
up slightly.
Since all the different copying methods are different across supported
operating systems, it's better to move this logic to where the rubber
meets the road.

This replicates the behavior of the FileStream instance that used to be
used by the managed portion of this API.
The input file is now locked correctly with shared lock instead of
exclusive one. The output file is locked with exclusive lock to
match previous behavior of .NET Core 3.0.

Added comment explaining why explict unlocking in necessary before
closing the file.
@danmoseley
Copy link
Member

@filipnavara I apologize for the delay - I assume this is still waiting for review.

@carlossanlop @jozkee from discussion with @stephentoub I think it's important we take this (or reverse the original break) to resolve a breaking change since 3.1. Could one of you please shepherd this?

@danmoseley danmoseley requested a review from jozkee August 10, 2020 22:22
@danmoseley
Copy link
Member

At this point reverting the original change might be safest (?)

cc @stephentoub

@filipnavara
Copy link
Member Author

I am open to either finishing this PR or reverting the original one. I wanted to produce some benchmarks to show the benefit of the change but due to many unforseen circumstances I ended up stranded in different countries and recently most of my test hardware was stolen. It may take me a few days to get back some reasonable setup to test the PR but I am committed to doing it.

@stephentoub
Copy link
Member

@filipnavara, I'm very sorry to hear about all your troubles. Please let us know if we can help with anything.

At this point, we should revert, and try again for 6.0.

Thanks!

@danmoseley
Copy link
Member

@stephentoub that means to revert 02ba75a right? Looks like that will need some conflict fixing.

@carlossanlop
Copy link
Member

@jozkee will work on reverting that change.

@danmoseley
Copy link
Member

@filipnavara that sounds like an awful experience, I'm sorry to hear about it. We appreciate your work, and it's too bad it didn't quite make this release, but it's unlikely to be wasted.

@danmoseley danmoseley modified the milestones: 5.0.0, Future Sep 1, 2020
@stephentoub
Copy link
Member

@filipnavara, thanks for all your work on this. Seems like this PR should be closed and we can start with a new one from scratch if you're still interested in trying to make this work?

@filipnavara
Copy link
Member Author

We can either close it or I can reapply the commits and rebase it. Not sure what is better.

@stephentoub
Copy link
Member

Thanks, @filipnavara. Let's close this then and start over with a new PR. Hopefully we can find a clean approach that achieves your perf goals while maintaining most of the code in C# and avoiding the managed/native duplication. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
@filipnavara filipnavara deleted the pr-1495 branch April 21, 2021 10:54
@rainersigwald
Copy link
Member

Did this ever get picked up again? This weekend, I wondered if we should have MSBuild do clonefile and then found a few issues where we wouldn't have to because it would be done for us, but the current state is "backed out" and I don't see a work item to track for the "hopefully we can turn it back on in 6.0" part. Am I missing one?

@danmoseley
Copy link
Member

@rainersigwald it did not.

@rainersigwald
Copy link
Member

https://twitter.com/filipnavara/status/1399839335256633348?s=20 -- @filipnavara is still thinking about it, but no tracking issue at the moment. Thanks, folks!

@dotnet dotnet unlocked this conversation Jun 2, 2021
@filipnavara
Copy link
Member Author

I am planning to revive this along with more unit tests and benchmarks. The primary motivation was to speed up our builds on macOS. It's mostly a convenience thing for us since it's not something that affects the product we ship to customers. I was prioritizing lately PRs that were blocking migration of our product to net6.0, some of which require coordination on different repositories (eg. Xamarin). That said, it is getting on top of my backlog again.

@stephentoub
Copy link
Member

@adamsitnik, @carlossanlop, @jozkee, @jeffhandley ... one of the issues hit here originally was related to the FileShare functionality we attempt to partially mimic on Unix. As such, whatever decision is made on #44546 will impact work done here.

@ghost ghost locked as resolved and limited conversation to collaborators Jul 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants