This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MVFS results


On Jul 20 15:02, Eric Blake wrote:
> Corinna Vinschen <corinna-cygwin <at> cygwin.com> writes:
> > > Found the root cause.  R/O vs. writeable.> 
> > 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?
> 
> Maybe this will help:  In the 'cp -p' case, get_handle() is true, and at that 
> point of cp's execution, the file is still writable (the chmod comes later).  
> In the 'touch -r' case, get_handle() is false, and the file is read-only.  But 
> in both cases, NtSetInformationFile has status 0.
> 
> For the 'touch -r' case, doing stat in another window shows no difference in 
> the timestamp between lines 1314 and 1317; in other words, it requires closing 
> the file for the time change to take effect.
> 
> So, the problem is that timestamp modification gets lost as part of fchmod 
> calling NtSetAttributesFile to remove the write permissions.  Even more, my 
> debugging was quite slow, with a big lag between when the file was created and 
> when the fchmod took place; but rather than using the current time, the fchmod 
> was able to remember the time the file was created.  I also noticed that 
> NtSetAttributesFile was instantaneous - I did not have to wait for the fd to 
> close to see the effects.

Just to be sure.  This does not occur with cp -p on other filesystems
than MVFS, right?  I don't see that problem on NTFS or FAT.

fchmod/NtSetAttributesFile calls NtSetInformationFile(FileBasicInformation)
with all timestamps set to 0, which means "don't touch them".  That works
fine on NTFS and FAT, so it's another bug of MVFS.

> Is there a way to force utimens to flush pending changes to disk, short of 
> closing and re-opening the fd?

Not that I'm aware of.  I don't know any mechanism for flushing metadata
changes except for NtClose.

Maybe(!) a FlushFileBuffer call will also flush metadata changes:

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	20 Jul 2009 15:26:15 -0000
@@ -1313,6 +1313,8 @@ fhandler_base::utimens_fs (const struct 
   fbi.FileAttributes = 0;
   NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
 					  FileBasicInformation);
+  if (NT_SUCCESS (status) && pc.fs_is_mvfs ())
+    FlushFileBuffers (get_handle ());
   if (closeit)
     close_fs ();
   /* Opening a directory on a 9x share from a NT machine works(!), but

Other than that, I can only suggest a change like this one:

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	20 Jul 2009 15:35:24 -0000
@@ -1306,13 +1306,31 @@ fhandler_base::utimens_fs (const struct 
 
   IO_STATUS_BLOCK io;
   FILE_BASIC_INFORMATION fbi;
+  NTSTATUS status;
   fbi.CreationTime.QuadPart = 0LL;
   fbi.LastAccessTime = lastaccess;
   fbi.LastWriteTime = lastwrite;
   fbi.ChangeTime.QuadPart = 0LL;
   fbi.FileAttributes = 0;
-  NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
-					  FileBasicInformation);
+  if (pc.fs_is_mvfs () && !closeit)
+    {
+      OBJECT_ATTRIBUTES attr;
+      HANDLE fh;
+
+      InitializeObjectAttributes (&attr, &ro_u_empty, pc.objcaseinsensitive (),
+				  fh, NULL);
+      status = NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES, &attr, &io,
+			   FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+      if (NT_SUCCESS (status))
+	{
+	  status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
+					 FileBasicInformation);
+	  NtClose (fh);
+	}
+    }
+  else
+    status = 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


> Or do we teach fchmod to honor pending 
> timestamp changes?

The problem is that the calls are stateless.  The fchmod call doesn't
know about a former utimens call and vice versa.  Worse, to do that
really correct you would not only have to keep track of the timestamp as
set by utimens, you would also have to keep track of them in case of
write.  That's a can of worms if you ask me.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]