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

Enable File.Copy to EXFAT volumes when not running as root #46027

Merged
3 commits merged into from
Dec 15, 2020

Conversation

danmoseley
Copy link
Member

@danmoseley danmoseley commented Dec 14, 2020

Fixes #45730

In File.Copy on Linux, after successfully copying the file we copy over the access and modified time, and copy the access permissions. See #16366 for why this was done: it's because on Windows, CopyFileEx preserves them, and some programs took a dependency on this e.g., for up to dateness checks, and arguably it's always been documented that File.Copy copies 'attributes'.

The problem on exfat volumes is that this file system does not store POSIX ownership; when viewed from Linux, all files appear to be owned by root. When we copy to such a volume, the copy succeeds if we have write permissions, but subsequently setting the timestamps and access permissions fails because (unless running as root) we need to own the file, and only root owns it. This manifests as System.IO.IOException: Operation not permitted. even though the file is successfully copied.

The workaround if you want to copy to an exfat volume on Linux is to either implement File.Copy yourself, or run as root.

The fix is to ignore EPERM when setting the time stamps and permissions. That gives a reasonable outcome, the file is copied in the best way that we can achieve given the filesystem limitations.

Note that "touch" does succeed against files on exfat if you do not supply a time -- the man page for utimensat notes that to set current time only requires write access, to set a specific time requires ownership rights or sufficient privileges (eg., root) -- and on exfat, only root ever has ownership rights. Conceivably we could at least set the current time, therefore, but it's not clear that's an improvement.

I don't think there's a good way to write a test but I tested manually on an exfat volume.

@danmoseley
Copy link
Member Author

Test failure is #44657

@danmoseley
Copy link
Member Author

This also impacts FileInfo.CopyTo

@danmoseley
Copy link
Member Author

@jozkee any chance you could take a quick look?

Copy link
Member

@jozkee jozkee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable to me. Thanks!

I don't think there's a good way to write a test but I tested manually on an exfat volume.

Not required for this PR but if you think is valuable to have the manual test you could consider adding it to https://github.com/dotnet/runtime/blob/master/src/libraries/System.IO.FileSystem/tests/ManualTests/ManualTests.cs

@jozkee
Copy link
Member

jozkee commented Dec 15, 2020

@danmosemsft forgot to ask, is there a problem if you run the same scenario on Windows? I wonder if this might cause a platform inconsistency.

@danmoseley
Copy link
Member Author

@jozkee that should not be a problem, as on Windows we don't copy the attributes -- Windows itself does, inside CopyFileEx. That's what our Unix implementation is trying to mimic.

@danmoseley
Copy link
Member Author

added manual test

@ghost
Copy link

ghost commented Dec 15, 2020

Hello @danmosemsft!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 264af40 into dotnet:master Dec 15, 2020
@danmoseley danmoseley deleted the file.copyto branch December 20, 2020 03:21
@ghost ghost locked as resolved and limited conversation to collaborators Jan 19, 2021
This pull request was closed.
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.

FileInfo.CopyTo UnauthorizedAccessException Error on Copying File to exFAT Drive in Linux
2 participants