delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2010/09/13/17:20:32

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD
X-Spam-Check-By: sourceware.org
Message-ID: <4C8E958B.1040807@ixiacom.com>
Date: Mon, 13 Sep 2010 14:20:11 -0700
From: Earl Chew <echew AT ixiacom DOT com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.9) Gecko/20100825 Thunderbird/3.1.3
MIME-Version: 1.0
To: <cygwin AT cygwin DOT com>
Subject: Deletion race in NtSetFileInformation ? (Directory not empty error in rm -r -f)
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

I have a Makefile which performs "rm -f -r" as part of a clean target.
On Win7 with 1.7.5-1 this can fail with:

rm -f -r win32
rm: cannot remove directory `win32': Directory not empty


I tried 1.7.7-1 but the problem still seems to be there.


Doing a little digging, I find that /bin/rm calls
unlinkat("win32/dll"), which eventually calls unlink_nt().


A short time later, /bin/rm calls unlink_at("win32") and
fails at check_dir_not_empty() because it finds the following
entries::

 413407 [main] rm 3612 check_dir_not_empty: File name: 2 0x2E 0x610E 0x10 "."
 413493 [main] rm 3612 check_dir_not_empty: File name: 4 0x2E 0x2E 0x18   ".."
 413574 [main] rm 3612 check_dir_not_empty: File name: 6 0x64 0x6C 0x6C   "dll"

Huh?  Wasn't this the directory that was just deleted?

Taking a look in the directory after the fact shows that the parent directory
appears to be empty :

W:> dir win32
 Volume in drive W is OS
 Volume Serial Number is C0E0-BBEE

 Directory of W:\cerberus\acl\col_\ato\win32

13/09/2010  01:57 PM    <DIR>          .
13/09/2010  01:57 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  392,720,297,984 bytes free


Hmm ... my reading of unlink_nt() is that the directory "win32/dll"
is deleted by setting FileDispositionInformation via NtSetFileInformation().

Since the file entry seems to be found during the subsequent check_dir_not_empty()
call when trying to delete the parent directory, is some form
of explicit synchronisation required when deleting
the child "win32/dll" to be sure that the deletion is
actually complete?


Earl

--
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

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019