On Jul 17 23:15, Eric Blake wrote: > Eric Blake <ebb9 <at> byu.net> writes: > > > > As I said above, I assume that MVFS has a problem similar to what we > > > have for remote HPFS. It's not sufficient to set only the minimal > > > set of access flags in calls to NtCreateFile/NtOpenFile in some > > > circumstances. I can't tell where the problem is for cp -p since that > > > shouldn't call anything different from touch in terms of setting > > > timestamps. > > > > utimensat vs utimens? > > Found the root cause. R/O vs. writeable. Doesn't matter where the source > file > lives; rather, the utimens call is failing because cp is changing the > permissions to R/O prior to changing the times, all while keeping the same fd > open that was used for populating the copy. But touch starts from a closed > fd, > which is enough of a different path to trigger the workaround path that > temporarily removes the R/O bit to change the time and then turn the bit back > on. Is that enough for you to go on, or do I need to also give strace > details?
It's not, unfortunately. There is no code path in Cygwin's utimens and friends which temorarily resets the R/O attribute. If the R/O attribute is actually removed temporarily, then touch calls chmod or something. The core function is fhandler_disk_file.cc, fhandler_base::utimens_fs(). It would be cool if you culd step through it to see how it behaves differently and examine the DOS attributes while doing that. What's the status code returned by the NtSetInformationFile call? And here's something you could try: Index: fhandler_disk_file.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/fhandler_disk_file.cc,v retrieving revision 1.302 diff -u -p -r1.302 fhandler_disk_file.cc --- fhandler_disk_file.cc 16 Jul 2009 15:28:57 -0000 1.302 +++ fhandler_disk_file.cc 18 Jul 2009 10:07:14 -0000 @@ -1311,8 +1311,19 @@ fhandler_base::utimens_fs (const struct fbi.LastWriteTime = lastwrite; fbi.ChangeTime.QuadPart = 0LL; fbi.FileAttributes = 0; + fbi.FileAttributes = pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY; + if (!fbi.FileAttributes) + fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL; NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi, FileBasicInformation); + if (NT_SUCCESS (status) && (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)) + { + /* Reset R/O attribute. */ + fbi.LastAccessTime.QuadPart = fbi.LastWriteTime.QuadPart = 0LL; + fbi.FileAttributes = pc.file_attributes (); + NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi, + FileBasicInformation); + } if (closeit) close_fs (); /* Opening a directory on a 9x share from a NT machine works(!), but I don't know if MVFS groks to remove the R/O attribute at the same time as setting the timestamps, but it's worth a try. If that doesn't work, we need mvfs-specific code like if (mvfs && (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)) { memset (&fbi, 0, sizeof fbi); fbi.FileAttributes = pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY; if (!fbi.FileAttributes) fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL; NtSetInformationFile (...); } fbi.LastAccessTime = lastaccess; fbi.LastWriteTime = lastwrite; fbi.FileAttributes = 0; NtSetInformationFile (...); if (mvfs && (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)) { fbi.LastAccessTime.QuadPart = fbi.LastWriteTime.QuadPart = 0LL; fbi.FileAttributes = pc.file_attributes (); NtSetInformationFile (...); } Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple