delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/10/12/15:57:15

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
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
From: ericblake AT comcast DOT net (Eric Blake)
To: Jim Meyering <jim AT meyering DOT net>
Cc: bug-coreutils AT gnu DOT org, cygwin AT cygwin DOT com
Subject: Re: mkdir -p and EROFS
Date: Wed, 12 Oct 2005 19:57:04 +0000
Message-Id: <101220051957.877.434D6A90000848A80000036D22007510900A050E040D0C079D0A@comcast.net>
MIME-Version: 1.0
Note-from-DJ: This may be spam

--NextPart_Webmail_9m3u9jl4l_877_1129147024_0
Content-Type: text/plain
Content-Transfer-Encoding: 8bit

> ericblake AT comcast DOT net (Eric Blake) wrote:
> > The algorithm change between 5.3.0 and 5.90 in lib/mkdir-p.c to
> > try mkdir() first instead of stat(), and key off of EEXIST, breaks
> > when mkdir() fails with EROFS on an intermediate directory when
> > the writable directory has been mounted inside a read-only tree.
> 
> Are you sure 5.3.0 behaved differently in this case?

Yes.  With unmodified 5.3.0, the sequence flat out fails (it was
post 5.3.0 where Paul added a patch to respect leading // as
different from /).  In the cygwin distro of 5.3.0, where I backported
the first cut of Paul's patch, the sequence of calls is:

make_path("//EBLAKE/share/dir", ...)
  stat("//EBLAKE/share/dir") => ENOENT
  chdir("//")
  make_dir("EBLAKE", "//EBLAKE", ...)
    mkdir("EBLAKE") => EROFS, ignored
    stat("EBLAKE")
  chdir("EBLAKE")
  make_dir("share", "//EBLAKE/share", ...)
    mkdir("share") => EEXIST, ignored
    stat("share")
  chdir("share")
  make_dir("dir", "//EBLAKE/share/dir", ...)
    mkdir("dir")

Subsequent changes were made prior to 5.90, including renaming
the file and method to perform the optimizations of reducing
syscalls, so the sequence of calls is now:

make_dir_parents("//EBLAKE/share/dir", ...)
  stat("//EBLAKE/share/dir") => ENOENT
  chdir("//")
  mkdir("EBLAKE") => EROFS, not EEXIST or ENOSYS
  error(0, EROFS, "cannot create directory %s", "//EBLAKE")

> The recent algorithm change was merely to eliminate the optimization
> of initially stat'ing the full directory name.  In your example,
> that stat would fail and the function would end up performing the same
> operations the 5.90 version performs.

The difference is not the mkdir() failing with EROFS, but that
5.90 no longer does an (otherwise) redundant stat when
mkdir fails.  With the errno being set to a non-intuitive
value of EROFS, information was lost compared to setting
it to EEXIST.

> 
> If mkdir-p.c were to handle Cygwin's EROFS like ENOSYS, we'd have to add
> code to distinguish a legitimate EROFS (because a missing destination
> directory cannot be created) from a cygwin-style should-be-EEXIST one.
> That feels too kludgy.

Not necessarily - the point of make_dir_parents optimization
on EEXIST is that even though mkdir will fail with EEXIST when
the file existed as a regular file, as opposed to a directory, the
subsequent chdir() prior to the next component in the chain
will catch that without the need for an intermediate stat().
Treating EROFS as EEXIST will lead to the same end behavior,
with regards to mkdir(1) (ie. mkdir -p will either verify the
complete named path exists, or die with some form of
reasonable error in the process).

2005-10-12  Eric Blake  <ebb9 AT byu DOT net>

	* mkdir-p.c (make_dir_parents): Treat EROFS like EEXIST.  Works
	around cygwin bug where EROFS is favored over EEXIST.

--
Eric Blake



--NextPart_Webmail_9m3u9jl4l_877_1129147024_0
Content-Type: application/octet-stream; name="coreutils.patch1"
Content-Transfer-Encoding: 7bit

Index: lib/mkdir-p.c
===================================================================
RCS file: /cvsroot/coreutils/coreutils/lib/mkdir-p.c,v
retrieving revision 1.11
diff -u -r1.11 mkdir-p.c
--- lib/mkdir-p.c	22 Sep 2005 05:42:26 -0000	1.11
+++ lib/mkdir-p.c	12 Oct 2005 19:52:28 -0000
@@ -49,6 +49,10 @@
 # define ENOSYS EEXIST
 #endif
 
+#ifndef EROFS
+# define EROFS EEXIST
+#endif
+
 #define WX_USR (S_IWUSR | S_IXUSR)
 
 /* Ensure that the directory ARG exists.
@@ -215,14 +219,18 @@
 		  leading_dirs = new;
 		}
 	    }
-	  else if (errno == EEXIST || errno == ENOSYS)
+	  else if (errno == EEXIST || errno == ENOSYS || errno == EROFS)
 	    {
 	      /* A file is already there.  Perhaps it is a directory.
 		 If not, it will be diagnosed later.
 
 		 The ENOSYS is for Solaris 8 NFS clients, which can
 		 fail with errno == ENOSYS if mkdir is invoked on an
-		 NFS mount point.  */
+		 NFS mount point.
+
+		 The EROFS is for cygwin, which can fail with
+		 errno == EROFS if the file exists but is part of a
+		 read only file system.  */
 	    }
 	  else
 	    {


--NextPart_Webmail_9m3u9jl4l_877_1129147024_0
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--NextPart_Webmail_9m3u9jl4l_877_1129147024_0--

- Raw text -


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