-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
fs::copy
fails copying '.git' dir from Linux to Windows(SMB)
#131026
Comments
Do you actually have permission? Does copying using |
Yeah, I have the read permission for the file, and the write permission for the target folder.
Yeah, I run the execve("./target/debug/fs-copy", ["./target/debug/fs-copy"], 0x7fff3c076090 /* 66 vars */) = 0
brk(NULL) = 0x56c871f58000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=176339, ...}) = 0
mmap(NULL, 176339, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f1cd547000
close(3) = 0
openat(AT_FDCWD, "/usr/lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\0\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=915712, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f1cd545000
mmap(NULL, 184808, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f1cd517000
mmap(0x76f1cd51b000, 147456, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x76f1cd51b000
mmap(0x76f1cd53f000, 16384, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x76f1cd53f000
mmap(0x76f1cd543000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2b000) = 0x76f1cd543000
close(3) = 0
openat(AT_FDCWD, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340_\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
fstat(3, {st_mode=S_IFREG|0755, st_size=2014520, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2034616, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76f1cd326000
mmap(0x76f1cd34a000, 1511424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0x76f1cd34a000
mmap(0x76f1cd4bb000, 319488, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x195000) = 0x76f1cd4bb000
mmap(0x76f1cd509000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e3000) = 0x76f1cd509000
mmap(0x76f1cd50f000, 31672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76f1cd50f000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f1cd323000
arch_prctl(ARCH_SET_FS, 0x76f1cd323780) = 0
set_tid_address(0x76f1cd323a50) = 8421
set_robust_list(0x76f1cd323a60, 24) = 0
rseq(0x76f1cd3240a0, 0x20, 0, 0x53053053) = 0
mprotect(0x76f1cd509000, 16384, PROT_READ) = 0
mprotect(0x76f1cd543000, 4096, PROT_READ) = 0
mprotect(0x56c86b4d1000, 12288, PROT_READ) = 0
mprotect(0x76f1cd5ad000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x76f1cd547000, 176339) = 0
poll([{fd=0, events=0}, {fd=1, events=0}, {fd=2, events=0}], 3, 0) = 0 (Timeout)
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x76f1cd3631d0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
getrandom("\xd6\x5d\xa8\x65\xa2\x1e\x5e\x63", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x56c871f58000
brk(0x56c871f79000) = 0x56c871f79000
openat(AT_FDCWD, "/proc/self/maps", O_RDONLY|O_CLOEXEC) = 3
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "56c86b47f000-56c86b485000 r--p 0"..., 1024) = 1024
read(3, "p 001e3000 103:02 658867 "..., 1024) = 1024
read(3, "xp 00001000 103:02 658789 "..., 1024) = 549
close(3) = 0
sched_getaffinity(8421, 32, [0 1 2 3 4 5 6 7 8 9 10 11]) = 8
rt_sigaction(SIGSEGV, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGSEGV, {sa_handler=0x56c86b4a4e40, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x76f1cd3631d0}, NULL, 8) = 0
rt_sigaction(SIGBUS, NULL, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGBUS, {sa_handler=0x56c86b4a4e40, sa_mask=[], sa_flags=SA_RESTORER|SA_ONSTACK|SA_SIGINFO, sa_restorer=0x76f1cd3631d0}, NULL, 8) = 0
sigaltstack(NULL, {ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=0}) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x76f1cd570000
mprotect(0x76f1cd570000, 4096, PROT_NONE) = 0
sigaltstack({ss_sp=0x76f1cd571000, ss_flags=0, ss_size=8192}, NULL) = 0
openat(AT_FDCWD, "/home/tlss/repos/my-own-swordsmam-bilibili-danmu/.git/objects/pack/pack-d2e66015bbbc4e376941d6b59325b32cd94baac2.idx", O_RDONLY|O_CLOEXEC) = 3
statx(3, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=21176, ...}) = 0
openat(AT_FDCWD, "/home/tlss/win-share/18tb/temp/target.idx", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0100444) = -1 EACCES (Permission denied)
close(3) = 0
write(2, "thread '", 8thread ') = 8
write(2, "main", 4main) = 4
write(2, "' panicked at ", 14' panicked at ) = 14
write(2, "src/main.rs", 11src/main.rs) = 11
write(2, ":", 1:) = 1
write(2, "6", 16) = 1
write(2, ":", 1:) = 1
write(2, "54", 254) = 2
write(2, ":\n", 2:
) = 2
write(2, "called `Result::unwrap()` on an "..., 114called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }) = 114
write(2, "\n", 1
) = 1
write(2, "note: run with `RUST_BACKTRACE=1"..., 78note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
) = 78
futex(0x76f1cd544070, FUTEX_WAKE_PRIVATE, 2147483647) = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x76f1cd570000, 12288) = 0
exit_group(101) = ?
+++ exited with 101 +++ |
What's the windows share mounted with? The kernel's SMB driver or a FUSE implementation? You can check via |
Hrrm, the 1 there looks sus, maybe we shouldn't be passing through all the bits from st_mode. On the other hand the openat2 manpage says:
so the extra bits should be fine with |
Or maybe windows/smb doesn't support unix semantics of open where the current FD permissions can be different from the on-disk mode that only affect subsequent opens. @TobisLee does the copy succeed if you make the source file writable? |
Hey @the8472, thanks for your help. Here's some information that might be useful.
I use the kernel's SMB driver. > grep win-share /proc/mounts
//192.168.2.5/h /home/tlss/win-share/18tb cifs rw,relatime,vers=3.1.1,cache=strict,username=tlss1,uid=1000,forceuid,gid=0,noforcegid,addr=192.168.2.5,file_mode=0755,dir_mode=0755,soft,nounix,serverino,mapposix,reparse=nfs,rsize=4194304,wsize=4194304,bsize=1048576,retrans=1,echo_interval=60,actimeo=1,closetimeo=1 0 0
No, still got the same error. |
Then does the target file already exist with permissions that would prevent it from being overwritten? |
Ah, yes, there is a target file already exists, after I delete the file, and rerun the code, the target file is copied successfully. |
Then I think there's no problem here. $ touch a && touch b && chmod -w b && cp a b
cp: cannot create regular file 'b': Permission denied |
Sorry, I am not sure I understand you correctly. As you said, when the target file ('b') exists, the copy will fail. But at the first time, there is no target file in the destination directory, and I run the code, I got the error. It's more like: $ touch a && chmod -w a && cp a b And the second time, after I add writable permission to source file, the code run successfully. |
I'm not sure if I understand the order of events correctly. Can you provide complete procedures of what does and what doesn't work? |
If the file have write permission, then the code will run successfully, the file will be copied. Otherwise, the code will fail. The I record a video to show the complete procedures. _20241001_171130.webm |
Ok, then I suspect this is an issue with windows or the cifs driver that it can't open-create a file for writing and simultanously give it read-only permissions. Setting the permissions early is intentional: #58803 Can you verify that this fails on the windows share but succeeds on your local drives? use std::os::unix::fs::OpenOptionsExt;
use std::fs::OpenOptions;
fn main() {
let path = "....";
OpenOptions::new().mode(0o444).write(true).create(true).truncate(true).open(path).expect("should succeed");
} |
Yeah, I run the code you provided, it fails on windows but succeeds on my local drives. Thanks for your help, I'll look the reason that setting the permissions early. Is there some workarounds I can do to avoid this? |
At the moment your options are
For reference, which linux kernel version and which windows version are you using?
I see that you're mounting with |
Thanks for your advice, you're so nice.
My linux version is: Linux arch 6.10.10-arch1-1
I don't use the //192.168.2.5/h /home/tlss/win-share/18tb cifs _netdev,nofail,username=usr,password=pwd,uid=1000 0 0 I try to add
Is there any other way to mount without |
Ah turns out windows doesn't support the unix extensions, it's a samba thing. |
All right. Then I'll try other network file share protocols. Huge thanks for your help. I'll close this issue. |
I tried to copy a git repository from Linux host to Windows host using
yazi
. And I noticed that there are some files in.git
dir are copied failed. The error ispermission denied
. I reported toyazi
(see sxyazi/yazi#1703). But it seemsyazi
just call thestd::fs::copy
to copy files. And I tried the following code:I expected to see this happen:
File
pack-d2e6xxxc2.idx
is copied to Windows directory.Instead, this happened:
Error: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }
Meta
rustc --version --verbose
:Backtrace
The text was updated successfully, but these errors were encountered: