> [EMAIL PROTECTED] (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 <[EMAIL PROTECTED]> * mkdir-p.c (make_dir_parents): Treat EROFS like EEXIST. Works around cygwin bug where EROFS is favored over EEXIST. -- Eric Blake
coreutils.patch1
Description: Binary data
-- 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/