X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org Date: Thu, 16 Jul 2009 17:11:21 +0200 From: Corinna Vinschen To: cygwin AT cygwin DOT com Subject: Re: MVFS results Message-ID: <20090716151121.GO27613@calimero.vinschen.de> Reply-To: cygwin AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com References: <20090715204831 DOT GA27613 AT calimero DOT vinschen DOT de> <20090716090703 DOT GH27613 AT calimero DOT vinschen DOT de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.19 (2009-02-20) Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com On Jul 16 13:58, Eric Blake wrote: > Corinna Vinschen cygwin.com> writes: > > For instance, maybe it chokes on the sharing flags. I'd try with > > FILE_SHARE_VALID_FLAGS instead of just FILE_SHARE_DELETE. > > > > Btw., it's very helpful to observe what happens exactly using > > sysinternal's procmon. > > What would you like to see? Here's a few procman entries captured immediately I can't make a lot out of the output without the chance to try what's going on when changing the arguments. In the first place I mentioned it for your convenience. But let's see... > [...] > 7:39:53.9322032 AM rm.exe 5912 QueryAllInformationFile > G:\views\fabt_eblake.vws\.s\00049\800039b14a4a8b07foo BUFFER OVERFLOW > CreationTime: 7/15/2009 3:42:16 PM, LastAccessTime: 7/15/2009 3:42:16 > PM, LastWriteTime: 7/15/2009 3:42:16 PM, ChangeTime: 7/15/2009 3:42:16 PM, > FileAttributes: RA, AllocationSize: 0, EndOfFile: 0, NumberOfLinks: 1, > DeletePending: False, Directory: False, IndexNumber: 0x47283402d42464, EaSize: > 0, Access: None, Position: 0, Mode: , AlignmentRequirement: Byte > > 7:40:37.3023584 AM rm.exe 5912 CreateFile > M:\u_fabt_eblake\FABT_Development\FABT_MPG_Process_BSP_SPCI\foo ACCESS > DENIED Desired Access: Generic Write, Delete, Disposition: Open, Options: Open > For Backup, Attributes: n/a, ShareMode: Delete, AllocationSize: n/a Yeah, ACCESS DENIED, but why? > Next, I'll have to play with your advice to play with the various ShareMode > flags. Yes, that's a chance. Another idea would be that the MVFS driver refuses the open request for DELETE *because* the R/O flag is set. That's wrong behaviour but it is as it is. If I'm right, you would have to open the file with FILE_WRITE_ATTRIBUTES permission only, remove the R/O flag, re-open the file with DELETE access, close the original handle, and then go ahead with the default unlink procedure, along these lines (tested on FAT): Index: syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.521 diff -u -p -r1.521 syscalls.cc --- syscalls.cc 14 Jul 2009 17:37:42 -0000 1.521 +++ syscalls.cc 16 Jul 2009 15:09:25 -0000 @@ -445,17 +445,13 @@ NTSTATUS unlink_nt (path_conv &pc) { NTSTATUS status; - HANDLE fh; + HANDLE fh, fh_ro = NULL; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; - ACCESS_MASK access = DELETE; - /* If the R/O attribute is set, we have to open the file with - FILE_WRITE_ATTRIBUTES to be able to remove this flags before trying - to delete it. */ - if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) - access |= FILE_WRITE_ATTRIBUTES; + bin_status bin_stat = dont_move; + ACCESS_MASK access = DELETE; ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT; /* Add the reparse point flag to native symlinks, otherwise we remove the target, not the symlink. */ @@ -463,13 +459,29 @@ unlink_nt (path_conv &pc) flags |= FILE_OPEN_REPARSE_POINT; pc.get_object_attr (attr, sec_none_nih); + /* If the R/O attribute is set, we have to open the file with + FILE_WRITE_ATTRIBUTES to be able to remove this flags before trying + to delete it. */ + if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) + { + access |= FILE_WRITE_ATTRIBUTES; + status = NtOpenFile (&fh_ro, FILE_WRITE_ATTRIBUTES, &attr, &io, + FILE_SHARE_VALID_FLAGS, flags); + if (NT_SUCCESS (status)) + { + NtSetAttributesFile (fh_ro, pc.file_attributes () + & ~FILE_ATTRIBUTE_READONLY); + InitializeObjectAttributes (&attr, &ro_u_empty, + pc.objcaseinsensitive (), fh_ro, NULL); + } + } + /* First try to open the file with only allowing sharing for delete. If the file has an open handle on it, other than just for deletion, this will fail. That indicates that the file has to be moved to the recycle bin so that it actually disappears from its directory even though its in use. Otherwise, if opening doesn't fail, the file is not in use and we can go straight to setting the delete disposition flag. */ - bin_status bin_stat = dont_move; status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags); if (status == STATUS_SHARING_VIOLATION || status == STATUS_LOCK_NOT_GRANTED) { @@ -512,11 +524,15 @@ unlink_nt (path_conv &pc) if (!NT_SUCCESS (status)) { NtClose (fh); + if (fh_ro) + NtClose (fh_ro); return status; } } } } + if (fh_ro) + NtClose (fh_ro); if (!NT_SUCCESS (status)) { if (status == STATUS_DELETE_PENDING) @@ -527,9 +543,6 @@ unlink_nt (path_conv &pc) syscall_printf ("Opening file for delete failed, status = %p", status); return status; } - /* Get rid of read-only attribute. */ - if (access & FILE_WRITE_ATTRIBUTES) - NtSetAttributesFile (fh, pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY); /* Try to move to bin if a sharing violation occured. If that worked, we're done. */ if (bin_stat == move_to_bin > [*] This was my first time using procmon - cool tool! Indeed! It was very helpful to figure out how the MSFT NFS client works. 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